kritzel-stencil 0.2.2 → 0.2.4

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 (85) hide show
  1. package/dist/cjs/index.cjs.js +1 -1
  2. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +83 -30
  3. package/dist/cjs/{workspace.migrations-BPwtowiJ.js → workspace.migrations-B89-6fP-.js} +42 -8
  4. package/dist/collection/classes/core/core.class.js +9 -2
  5. package/dist/collection/classes/handlers/line-handle.handler.js +1 -0
  6. package/dist/collection/classes/handlers/move.handler.js +2 -0
  7. package/dist/collection/classes/handlers/resize.handler.js +2 -0
  8. package/dist/collection/classes/handlers/rotation.handler.js +2 -0
  9. package/dist/collection/classes/structures/object-map.structure.js +44 -3
  10. package/dist/collection/classes/tools/brush-tool.class.js +2 -0
  11. package/dist/collection/classes/tools/eraser-tool.class.js +22 -8
  12. package/dist/collection/classes/tools/line-tool.class.js +2 -0
  13. package/dist/collection/classes/tools/shape-tool.class.js +1 -0
  14. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +5 -5
  15. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +7 -0
  16. package/dist/collection/components/shared/kritzel-dialog/kritzel-dialog.css +3 -2
  17. package/dist/collection/components/shared/kritzel-dialog/kritzel-dialog.js +3 -2
  18. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +7 -10
  19. package/dist/collection/components/ui/kritzel-current-user/kritzel-current-user.js +1 -1
  20. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.js +1 -1
  21. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
  22. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  23. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +1 -1
  24. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +1 -1
  25. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +2 -2
  26. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
  27. package/dist/collection/constants/version.js +1 -1
  28. package/dist/collection/themes/dark-theme.js +4 -0
  29. package/dist/collection/themes/light-theme.js +4 -0
  30. package/dist/components/index.js +1 -1
  31. package/dist/components/kritzel-awareness-cursors.js +1 -1
  32. package/dist/components/kritzel-color-palette.js +1 -1
  33. package/dist/components/kritzel-color.js +1 -1
  34. package/dist/components/kritzel-controls.js +1 -1
  35. package/dist/components/kritzel-current-user-dialog.js +1 -1
  36. package/dist/components/kritzel-current-user.js +1 -1
  37. package/dist/components/kritzel-dialog.js +1 -1
  38. package/dist/components/kritzel-editor.js +1 -1
  39. package/dist/components/kritzel-engine.js +1 -1
  40. package/dist/components/kritzel-export.js +1 -1
  41. package/dist/components/kritzel-login-dialog.js +1 -1
  42. package/dist/components/kritzel-more-menu.js +1 -1
  43. package/dist/components/kritzel-settings.js +1 -1
  44. package/dist/components/kritzel-share-dialog.js +1 -1
  45. package/dist/components/kritzel-stroke-size.js +1 -1
  46. package/dist/components/kritzel-tool-config.js +1 -1
  47. package/dist/components/kritzel-utility-panel.js +1 -1
  48. package/dist/components/p-0F9_lw6l.js +1 -0
  49. package/dist/components/{p-DfB7uJ0N.js → p-3YivOJM2.js} +1 -1
  50. package/dist/components/p-B2dVTxsc.js +9 -0
  51. package/dist/components/{p-mYhFNPgz.js → p-BAjrJjMX.js} +1 -1
  52. package/dist/components/{p-R9M5PnAz.js → p-BDOSy6zd.js} +1 -1
  53. package/dist/components/{p-DE2xDwUM.js → p-BabNumqA.js} +1 -1
  54. package/dist/components/{p-574MVXxi.js → p-Be6E_RMf.js} +1 -1
  55. package/dist/components/{p-CoyqJSjT.js → p-BmYsz1bP.js} +1 -1
  56. package/dist/components/p-C-qyWv4d.js +1 -0
  57. package/dist/components/{p-BYOIzv_f.js → p-C1Fv9rVN.js} +1 -1
  58. package/dist/components/{p-Bfa-Amjn.js → p-C2MdRsg6.js} +1 -1
  59. package/dist/components/{p-u-827ZX7.js → p-CsMMZSAP.js} +1 -1
  60. package/dist/components/p-DMYfjC1C.js +1 -0
  61. package/dist/components/{p-Dxb22STM.js → p-DYHF_MSN.js} +1 -1
  62. package/dist/components/{p-BWrxz4mM.js → p-Dg_nGsFe.js} +1 -1
  63. package/dist/components/{p-BtJB7FsW.js → p-DoDI-v-H.js} +1 -1
  64. package/dist/components/p-Dqpa31TI.js +1 -0
  65. package/dist/components/p-R60vdaIY.js +1 -0
  66. package/dist/components/{p-CU6kJPth.js → p-ZpItdhxS.js} +1 -1
  67. package/dist/esm/index.js +2 -2
  68. package/dist/esm/kritzel-active-users_42.entry.js +83 -30
  69. package/dist/esm/{workspace.migrations-C_uxbvuH.js → workspace.migrations-D_y5zlxK.js} +42 -8
  70. package/dist/stencil/index.esm.js +1 -1
  71. package/dist/stencil/p-74898384.entry.js +9 -0
  72. package/dist/stencil/p-D_y5zlxK.js +1 -0
  73. package/dist/stencil/stencil.esm.js +1 -1
  74. package/dist/types/classes/structures/object-map.structure.d.ts +19 -0
  75. package/dist/types/constants/version.d.ts +1 -1
  76. package/dist/types/interfaces/theme.interface.d.ts +5 -5
  77. package/package.json +1 -1
  78. package/dist/components/p-BCzbwL4m.js +0 -1
  79. package/dist/components/p-BfJav4Zz.js +0 -1
  80. package/dist/components/p-BmcAX-1k.js +0 -1
  81. package/dist/components/p-C6Td7I4k.js +0 -1
  82. package/dist/components/p-CqYIRmoh.js +0 -1
  83. package/dist/components/p-DFeyobdy.js +0 -9
  84. package/dist/stencil/p-4d28c496.entry.js +0 -9
  85. package/dist/stencil/p-C_uxbvuH.js +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var workspace_migrations = require('./workspace.migrations-BPwtowiJ.js');
3
+ var workspace_migrations = require('./workspace.migrations-B89-6fP-.js');
4
4
  var Y = require('yjs');
5
5
  var yWebsocket = require('y-websocket');
6
6
  require('y-indexeddb');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-CFnj_FXt.js');
4
- var workspace_migrations = require('./workspace.migrations-BPwtowiJ.js');
4
+ var workspace_migrations = require('./workspace.migrations-B89-6fP-.js');
5
5
  var Y = require('yjs');
6
6
  require('y-indexeddb');
7
7
  require('y-websocket');
@@ -957,10 +957,7 @@ const KritzelControls = class {
957
957
  }
958
958
  handleDisplayValuesChange = (event) => {
959
959
  const newVal = event.detail;
960
- if (this.displayValues &&
961
- this.displayValues.color === newVal.color &&
962
- this.displayValues.size === newVal.size &&
963
- this.displayValues.fontFamily === newVal.fontFamily) {
960
+ if (this.displayValues && this.displayValues.color === newVal.color && this.displayValues.size === newVal.size && this.displayValues.fontFamily === newVal.fontFamily) {
964
961
  return;
965
962
  }
966
963
  this.displayValues = newVal;
@@ -1092,13 +1089,13 @@ const KritzelControls = class {
1092
1089
  // Separate tool controls from config control
1093
1090
  const toolControls = this.controls.filter(c => c.type === 'tool' || c.type === 'separator');
1094
1091
  const configControl = this.controls.find(c => c.type === 'config' && c.name === this.firstConfig?.name);
1095
- return (index.h(index.Host, { key: 'ea5e17d6995c228862b6d3375213b8f4ff05f04b', class: {
1092
+ return (index.h(index.Host, { key: '93d08a3268edb67fc4cccb291b6e0aff6cf5a4bd', class: {
1096
1093
  mobile: this.isTouchDevice,
1097
- } }, this.isUtilityPanelVisible && (index.h("kritzel-utility-panel", { key: '3296551d078f9d358efff1438fdcf723349fa5e1', style: {
1094
+ } }, this.isUtilityPanelVisible && (index.h("kritzel-utility-panel", { key: '8862ea7e524b3e23d87ffea2929e04df7231bb0c', style: {
1098
1095
  position: 'absolute',
1099
1096
  bottom: '56px',
1100
1097
  left: '12px',
1101
- }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), index.h("div", { key: '9cbea189d5875cda4f09dc7228345e0cb268d47d', class: "kritzel-controls" }, index.h("div", { key: '0df655a7ac5bd6bc164b82703bc212b480058ba2', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), index.h("div", { key: 'bc16b645b6c6a12ec6bd8420a8d84aee83d2b6d2', class: "kritzel-tools-scroll", ref: el => this.toolsScrollRef = el, onScroll: this.handleToolsScroll }, toolControls.map(control => {
1098
+ }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), index.h("div", { key: '2ea2a41ba4cda77f5abde9231d293da181a2a568', class: "kritzel-controls" }, index.h("div", { key: '6bd4f6d930a0a51d5549b6dbae1e7be14cbe7822', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), index.h("div", { key: 'c712ca502a4ebd244394158b39391a49839bc386', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
1102
1099
  // Check if this control has sub-options (split-button)
1103
1100
  if (control.subOptions?.length) {
1104
1101
  const selectedSubOption = this.getSelectedSubOption(control);
@@ -1128,10 +1125,10 @@ const KritzelControls = class {
1128
1125
  'kritzel-control': true,
1129
1126
  'selected': this.activeControl?.name === control?.name,
1130
1127
  }, key: control.name, "data-testid": `tool-${control.name}`, onClick: _event => this.handleControlClick?.(control) }, index.h("kritzel-icon", { name: control.icon })));
1131
- })), index.h("div", { key: '2e0824a991997d52168a3d922c2214ed66f5bf57', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (index.h("div", { class: {
1128
+ })), index.h("div", { key: '6ca260915b2880443a324855a1de96d10affd256', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (index.h("div", { class: {
1132
1129
  'kritzel-config-container': true,
1133
1130
  'visible': hasConfigUI,
1134
- }, key: configControl.name }, index.h("div", { key: 'd2cb554f56ce0f3bfe72e85fcbb506199387c15f', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), index.h("kritzel-tooltip", { key: '39412859a99c71b536e0b2ed0045b671a975af7e', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, index.h("kritzel-tool-config", { key: '1977ceddd337df53e8636e2bddd1d928aca3a1ff', tool: this.activeControl.tool, theme: this.theme, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), index.h("div", { key: '06bd3bf3558931a0c2317e149d8990f42e77adae', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1131
+ }, key: configControl.name }, index.h("div", { key: '984d30bd7f508d2fc56a9e81692fdf05dfb852c9', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), index.h("kritzel-tooltip", { key: '90c59995d229c606b9bf3b625f6eefc0632371c6', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, index.h("kritzel-tool-config", { key: 'cdb56f983e1f6840b11d06d166f982a93c07331b', tool: this.activeControl.tool, theme: this.theme, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), index.h("div", { key: 'c79db07dd02995d3ee105e8d7a773f89cd7072a5', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1135
1132
  if (el)
1136
1133
  this.configTriggerRef = el;
1137
1134
  }, onKeyDown: event => {
@@ -1140,7 +1137,7 @@ const KritzelControls = class {
1140
1137
  }
1141
1138
  }, style: {
1142
1139
  cursor: 'pointer',
1143
- } }, this.activeControl.tool instanceof workspace_migrations.KritzelTextTool && this.displayValues ? (index.h("div", { class: "font-container" }, index.h("kritzel-font", { fontFamily: this.displayValues.fontFamily, size: this.displayValues.size, color: this.displayValues.color }))) : this.displayValues && (index.h("div", { class: "color-container" }, index.h("kritzel-color", { value: this.displayValues.color, theme: this.theme, size: this.displayValues.size, style: {
1140
+ } }, this.displayValues && (index.h("div", { key: '0573a22c3105076729eb986c98b7e8644392f767', class: "color-container" }, index.h("kritzel-color", { key: '1e9711c219a5c520873b3206072957f2d406c56c', value: this.displayValues.color, theme: this.theme, size: 18, style: {
1144
1141
  borderRadius: '50%',
1145
1142
  border: 'none',
1146
1143
  } })))))))));
@@ -1175,7 +1172,7 @@ const KritzelCurrentUser = class {
1175
1172
  this.dialogRef?.open();
1176
1173
  };
1177
1174
  render() {
1178
- return (index.h(index.Host, { key: 'a735cb9f16f4898fde0b52573affa2d270a8f1de' }, index.h("kritzel-avatar", { key: 'd449a515182718ab4ef3b26b2277696bbc7ab46f', user: this.user, size: this.avatarSize, onClick: this.handleAvatarClick }), index.h("kritzel-current-user-dialog", { key: '3542f6df43c9924218e344f70bdc398c74a8eae6', ref: el => (this.dialogRef = el), user: this.user })));
1175
+ return (index.h(index.Host, { key: 'c392caf731f8352fd8e2a95918fe48a2f00dd9e5' }, index.h("kritzel-avatar", { key: 'b3bdce0efa0c0610aa028303386c643d53bc8300', user: this.user, size: this.avatarSize, onClick: this.handleAvatarClick }), index.h("kritzel-current-user-dialog", { key: '5e7af1aea468028e091ad8f461e4352cb9f9636b', ref: el => (this.dialogRef = el), user: this.user })));
1179
1176
  }
1180
1177
  };
1181
1178
  KritzelCurrentUser.style = kritzelCurrentUserCss();
@@ -1207,7 +1204,7 @@ const KritzelCurrentUserDialog = class {
1207
1204
  }
1208
1205
  render() {
1209
1206
  const displayName = this.getDisplayName();
1210
- return (index.h(index.Host, { key: '40c1a1bed0ddf02f9835199b5f7d2363e4d1902b' }, index.h("kritzel-dialog", { key: '8d10cd2dbdec06c0519f5a8f6f0f113d30b978aa', dialogTitle: "Account", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, index.h("div", { key: '24d8267d37fde77ce1a26efb84a9eaa3320dd6b7', class: "user-info" }, index.h("kritzel-avatar", { key: '282153dea220d8aa4a509764e2dcbcf20a6f2682', user: this.user, size: 80 }), displayName && index.h("div", { key: '3a908e583a8eb0aca4020eb78d76821b82b1c643', class: "user-name" }, displayName), this.user?.email && index.h("div", { key: '2aadf821b6f91c6bd76f10ff234d94ab8b79dd9c', class: "user-email" }, this.user.email)))));
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)))));
1211
1208
  }
1212
1209
  };
1213
1210
  KritzelCurrentUserDialog.style = kritzelCurrentUserDialogCss();
@@ -1368,7 +1365,7 @@ class KritzelHTMLHelper {
1368
1365
  }
1369
1366
  }
1370
1367
 
1371
- 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){.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}.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}`;
1372
1369
 
1373
1370
  const KritzelDialog = class {
1374
1371
  constructor(hostRef) {
@@ -1470,8 +1467,9 @@ const KritzelDialog = class {
1470
1467
  document.body.style.overflow = 'hidden';
1471
1468
  }
1472
1469
  lockMobileViewportHeight() {
1473
- // Only lock height on mobile when fullscreenOnMobile is enabled
1474
- if (!this.fullscreenOnMobile || window.innerWidth > 576) {
1470
+ // Only lock height on mobile when fullscreenOnMobile is enabled.
1471
+ // Use the smaller dimension so landscape phones (wide but short) are also detected.
1472
+ if (!this.fullscreenOnMobile || Math.min(window.innerWidth, window.innerHeight) > 576) {
1475
1473
  this.mobileLockedHeight = null;
1476
1474
  return;
1477
1475
  }
@@ -21447,6 +21445,12 @@ class KritzelObjectMap {
21447
21445
  * redundant full serializations of every child object per frame.
21448
21446
  */
21449
21447
  _localOnlyMode = false;
21448
+ /**
21449
+ * Tracks whether we're currently executing inside a `transaction()`
21450
+ * callback. While true, `markUndoBoundary()` is a no-op so nested
21451
+ * insert/remove calls don't split the in-progress undo step.
21452
+ */
21453
+ _inTransaction = false;
21450
21454
  /**
21451
21455
  * Indicates whether the object map has been initialized and is ready for use.
21452
21456
  * @returns `true` if providers are connected and the map is operational
@@ -21685,9 +21689,12 @@ class KritzelObjectMap {
21685
21689
  }
21686
21690
  this._providers.push(provider);
21687
21691
  }
21688
- // Set up undo/redo manager for this workspace
21692
+ // captureTimeout is effectively infinite undo-step boundaries are
21693
+ // marked explicitly via markUndoBoundary() in insert/remove/reset and
21694
+ // at stroke/gesture boundaries in the tools. This prevents a single
21695
+ // brush stroke from being split when the user pauses after pointerdown.
21689
21696
  this._undoManager = new Y__namespace.UndoManager([this._objectsMap], {
21690
- captureTimeout: 200,
21697
+ captureTimeout: Number.MAX_SAFE_INTEGER,
21691
21698
  trackedOrigins: new Set(['local', 'temporary']),
21692
21699
  ignoreRemoteMapChanges: true,
21693
21700
  });
@@ -22005,9 +22012,35 @@ class KritzelObjectMap {
22005
22012
  */
22006
22013
  transaction(callback) {
22007
22014
  if (this._ydoc) {
22008
- this._ydoc.transact(callback, 'local');
22015
+ this._inTransaction = true;
22016
+ try {
22017
+ this._ydoc.transact(callback, 'local');
22018
+ }
22019
+ finally {
22020
+ this._inTransaction = false;
22021
+ }
22009
22022
  }
22010
22023
  }
22024
+ /**
22025
+ * Closes the current undo stack item so the next tracked change starts
22026
+ * a new one. Call at gesture/stroke boundaries (e.g. drag/resize/rotate
22027
+ * end, brush/line/shape stroke end).
22028
+ *
22029
+ * No-op while a transaction() is open.
22030
+ */
22031
+ stopUndoCapturing() {
22032
+ this.markUndoBoundary();
22033
+ }
22034
+ /**
22035
+ * Internal: closes the current undo stack item. No-op while inside a
22036
+ * transaction() so wrapped multi-op work stays a single undo step.
22037
+ */
22038
+ markUndoBoundary() {
22039
+ if (this._inTransaction) {
22040
+ return;
22041
+ }
22042
+ this._undoManager?.stopCapturing();
22043
+ }
22011
22044
  /**
22012
22045
  * Executes a callback where all update() calls only modify local state
22013
22046
  * (quadtree + idMap) without writing to Yjs. This avoids expensive full
@@ -22071,6 +22104,7 @@ class KritzelObjectMap {
22071
22104
  reset() {
22072
22105
  this.quadtree.reset();
22073
22106
  this._idMap.clear();
22107
+ this.markUndoBoundary();
22074
22108
  this._ydoc?.transact(() => {
22075
22109
  this._objectsMap?.clear();
22076
22110
  }, 'local');
@@ -22091,6 +22125,7 @@ class KritzelObjectMap {
22091
22125
  this._idMap.set(object.id, object);
22092
22126
  if (this._objectsMap && this.isPersistable(object)) {
22093
22127
  const serialized = object.serialize();
22128
+ this.markUndoBoundary();
22094
22129
  this._ydoc?.transact(() => {
22095
22130
  this._objectsMap?.set(object.id, serialized);
22096
22131
  }, 'local');
@@ -22135,6 +22170,10 @@ class KritzelObjectMap {
22135
22170
  */
22136
22171
  remove(predicate) {
22137
22172
  const objectsToRemove = this.quadtree.filter(predicate);
22173
+ if (objectsToRemove.length === 0) {
22174
+ return;
22175
+ }
22176
+ this.markUndoBoundary();
22138
22177
  for (const object of objectsToRemove) {
22139
22178
  this.quadtree.remove(o => o.id === object.id);
22140
22179
  this._idMap.delete(object.id);
@@ -23825,8 +23864,15 @@ class KritzelCore {
23825
23864
  if (!selectionGroup) {
23826
23865
  return;
23827
23866
  }
23828
- selectionGroup.objects.forEach(obj => this.removeObject(obj));
23829
- this.removeSelectionGroup();
23867
+ // Seal the selection group's creation into its own undo step so Yjs
23868
+ // doesn't collapse create+delete of the SG into a no-op on undo.
23869
+ this._store.objects.stopUndoCapturing();
23870
+ this._store.objects.transaction(() => {
23871
+ selectionGroup.objects.forEach(obj => this.removeObject(obj));
23872
+ this.removeSelectionGroup();
23873
+ });
23874
+ // Close the deletion step so subsequent unrelated changes start a new step.
23875
+ this._store.objects.stopUndoCapturing();
23830
23876
  this.engine.emitObjectsInViewportChange();
23831
23877
  this.rerender();
23832
23878
  }
@@ -25778,7 +25824,7 @@ async function toPng(node, options = {}) {
25778
25824
  return canvas.toDataURL();
25779
25825
  }
25780
25826
 
25781
- const kritzelEngineCss = () => `:host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.ProseMirror{outline:none}p,h1,h2,h3,h4,h5,h6,blockquote,pre{margin:0;padding:0}.workspace-loading-overlay{position:absolute;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;gap:10px;background-color:var(--kritzel-loading-overlay-background, rgba(255, 255, 255, 0.6));color:var(--kritzel-loading-overlay-color, #333);font-family:var(--kritzel-font-family, sans-serif);font-size:1.25rem;pointer-events:all;animation:workspace-loading-fade-in 200ms ease-out var(--kritzel-loading-overlay-delay, 300ms) forwards;opacity:0}.workspace-loading-spinner{width:20px;height:20px;box-sizing:border-box;display:block;flex-shrink:0;border:2px solid var(--kritzel-loading-overlay-spinner-color, #cccccc);border-top-color:var(--kritzel-loading-overlay-spinner-active-color, #333333);border-radius:50%;animation:workspace-loading-spin 0.6s linear infinite}@keyframes workspace-loading-spin{to{transform:rotate(360deg)}}@keyframes workspace-loading-fade-in{to{opacity:1}}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}.PlaygroundEditorTheme__quote{margin:0;margin-left:20px;margin-bottom:10px;font-size:15px;color:rgb(101, 103, 107);border-left-color:rgb(206, 208, 212);border-left-width:4px;border-left-style:solid;padding-left:16px}`;
25827
+ const kritzelEngineCss = () => `:host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.ProseMirror{outline:none}p,h1,h2,h3,h4,h5,h6,blockquote,pre{margin:0;padding:0}.workspace-loading-overlay{position:absolute;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;gap:10px;background-color:var(--kritzel-engine-loading-overlay-background, rgba(255, 255, 255, 0.6));color:var(--kritzel-engine-loading-overlay-color, #333);font-family:var(--kritzel-font-family, sans-serif);font-size:1.25rem;pointer-events:all;animation:workspace-loading-fade-in 200ms ease-out var(--kritzel-engine-loading-overlay-delay, 300ms) forwards;opacity:0}.workspace-loading-spinner{width:20px;height:20px;box-sizing:border-box;display:block;flex-shrink:0;border:2px solid var(--kritzel-engine-loading-overlay-spinner-color, #cccccc);border-top-color:var(--kritzel-engine-loading-overlay-spinner-active-color, #333333);border-radius:50%;animation:workspace-loading-spin 0.6s linear infinite}@keyframes workspace-loading-spin{to{transform:rotate(360deg)}}@keyframes workspace-loading-fade-in{to{opacity:1}}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}.PlaygroundEditorTheme__quote{margin:0;margin-left:20px;margin-bottom:10px;font-size:15px;color:rgb(101, 103, 107);border-left-color:rgb(206, 208, 212);border-left-width:4px;border-left-style:solid;padding-left:16px}`;
25782
25828
 
25783
25829
  const KritzelEngine = class {
25784
25830
  get host() { return index.getElement(this); }
@@ -26009,6 +26055,7 @@ const KritzelEngine = class {
26009
26055
  if (this.core.store.isDisabled) {
26010
26056
  return;
26011
26057
  }
26058
+ const wasTracked = this.core.store.state.pointers.has(ev.pointerId);
26012
26059
  this.core.store.state.pointers.delete(ev.pointerId);
26013
26060
  if (this.host.hasPointerCapture(ev.pointerId)) {
26014
26061
  this.host.releasePointerCapture(ev.pointerId);
@@ -26017,6 +26064,12 @@ const KritzelEngine = class {
26017
26064
  if (this.core.store.state.pointers.size === 0) {
26018
26065
  this.core.cursorManager.resetToDefault();
26019
26066
  }
26067
+ // If the corresponding pointerdown was never processed (e.g. consumed by a capture-phase
26068
+ // listener like a tooltip close handler), skip tool logic to avoid spurious interactions
26069
+ // such as a selected text object entering edit mode when clicking to dismiss a popup.
26070
+ if (!wasTracked) {
26071
+ return;
26072
+ }
26020
26073
  this.viewport.handlePointerUp(ev);
26021
26074
  this.core.store.state?.activeTool?.handlePointerUp(ev);
26022
26075
  }
@@ -27868,7 +27921,7 @@ const KritzelExport = class {
27868
27921
  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 })));
27869
27922
  }
27870
27923
  render() {
27871
- return (index.h(index.Host, { key: 'efeea781325e672e3f4c1579a50da1c928dc88b5' }, index.h("kritzel-dialog", { key: 'c5e60559a3022eec7d13a73b5ec858edb8e7ce1d', isOpen: this.isDialogOpen, dialogTitle: "Export", closable: true, onDialogClose: this.closeDialog }, index.h("div", { key: '1508001914a22cbb944502be7d33a04128548842', class: "export-content" }, index.h("kritzel-pill-tabs", { key: '9b0a21140fef986344d98b688729017cb66da493', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), index.h("button", { key: '70021cadab8b2840bbcf66afcd38c28c419facfe', class: "export-primary-button", onClick: this.handleExport }, "Export")))));
27924
+ 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")))));
27872
27925
  }
27873
27926
  };
27874
27927
  KritzelExport.style = kritzelExportCss();
@@ -28165,7 +28218,7 @@ const KritzelLoginDialog = class {
28165
28218
  this.dialogClosed.emit();
28166
28219
  };
28167
28220
  render() {
28168
- return (index.h(index.Host, { key: '8cac83db48fef2531f1669c3f601526b1e5cdefa' }, index.h("kritzel-dialog", { key: '72e0f2eb8e19f3c1081bfd5e1183aa9ed1bc678a', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, index.h("div", { key: 'bb17bcf6f3486000c9056b3983810e016b0f05a3', class: "login-content" }, this.subtitle && (index.h("p", { key: 'cef17bc6f5078769b8deed6ec1c615a71fe0c611', class: "login-subtitle" }, this.subtitle)), index.h("div", { key: '8462ef9a62201cb15f8911432ca188cf49bc8a8d', class: "login-providers" }, this.providers.map(provider => (index.h("button", { key: provider.name, class: {
28221
+ 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: {
28169
28222
  'provider-button': true,
28170
28223
  'is-loading': this.loadingProvider === provider.name,
28171
28224
  'is-disabled': this.loadingProvider !== null && this.loadingProvider !== provider.name,
@@ -28533,7 +28586,7 @@ const KritzelMoreMenu = class {
28533
28586
  this.closeMenu();
28534
28587
  };
28535
28588
  render() {
28536
- return (index.h(index.Host, { key: '1bf8b30bc9c958911e544121db01d74948fb2695', class: { mobile: this.isTouchDevice } }, index.h("div", { key: '3aab8140694f15db066f7c46f243ebc29fb698c1', class: { 'more-menu-wrapper': true, visible: this.visible } }, index.h("button", { key: '55799f62f7bf72af751362315d38dc8b226c0950', class: "more-menu-button", onClick: this.toggleMenu }, index.h("kritzel-icon", { key: 'ee627acfcad95a1a978fb3c46d428181bbcb98c1', name: this.icon, size: this.iconSize })), index.h("kritzel-portal", { key: 'e4116b6583e34dd915ffb46ee3b7377ea2ff10e8', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, index.h("kritzel-menu", { key: 'a9f50ddf822b14bad8723c67a202dcaa257b817a', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
28589
+ 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 })))));
28537
28590
  }
28538
28591
  };
28539
28592
  KritzelMoreMenu.style = kritzelMoreMenuCss();
@@ -29036,7 +29089,7 @@ const KritzelPortal = class {
29036
29089
  * This file is auto-generated by the version bump scripts.
29037
29090
  * Do not modify manually.
29038
29091
  */
29039
- const KRITZEL_VERSION = '0.2.2';
29092
+ const KRITZEL_VERSION = '0.2.4';
29040
29093
 
29041
29094
  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)}`;
29042
29095
 
@@ -29231,7 +29284,7 @@ const KritzelSettings = class {
29231
29284
  }
29232
29285
  }
29233
29286
  render() {
29234
- return (index.h(index.Host, { key: '33618317a3d4a60cda4369cde1e694cd13116d0a' }, index.h("kritzel-dialog", { key: '274de12d633d430628c1ac2f1ac9779596d0d249', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", onDialogClose: this.closeDialog }, index.h("kritzel-master-detail", { key: 'd771531248ec5db38b2d711334c74dde28985f91', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29287
+ return (index.h(index.Host, { key: '78a4eb80f2a4d9e7ef67d06bb39137dbde3a3301' }, index.h("kritzel-dialog", { key: '1adf437125186758f75dc085db9a4e0c572fccd9', isOpen: this.isDialogOpen, dialogTitle: "Settings", size: "large", onDialogClose: this.closeDialog }, index.h("kritzel-master-detail", { key: '68ed27f5c9c03589d0444c02ff0524dfcaa053a3', items: SETTINGS_CATEGORIES, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
29235
29288
  }
29236
29289
  };
29237
29290
  KritzelSettings.style = kritzelSettingsCss();
@@ -29357,9 +29410,9 @@ const KritzelShareDialog = class {
29357
29410
  this.dialogClosed.emit();
29358
29411
  };
29359
29412
  render() {
29360
- return (index.h(index.Host, { key: 'a104c14b2492d97f3ada98c9eaaa845d63074063' }, index.h("kritzel-dialog", { key: 'ae2155436f9dc7530dadfed5da92b2ae8781c3f5', dialogTitle: "Share Workspace", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small" }, index.h("div", { key: 'd419303e63e8183fec99ad2743d5d377c6b2b642', class: "share-content" }, index.h("div", { key: '913ee65831ff47e6d4d4ba2e26426892bc583827', class: "share-section" }, index.h("div", { key: 'c32d489e5f7891d23d133c1677c6022e9fc365ab', class: "share-row" }, index.h("div", { key: '1aa00b5578c657c20910bd1af44d166806d2fe3d', class: "share-label-group" }, index.h("label", { key: '2d00004314e0d1141397ee7af4e7f923e3182ebf', class: "share-label" }, "Link sharing"), index.h("p", { key: 'c698ba01de2b252cf6453e0d339044d78c0a701e', class: "share-description" }, this.internalIsPublic
29413
+ 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
29361
29414
  ? 'Anyone with the link can access this workspace.'
29362
- : 'Link sharing is disabled. Only you can access this workspace.')), index.h("kritzel-slide-toggle", { key: 'dcc56bf4644c2c56438115b0e9efae7e74ac77d7', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: "Enable link sharing" }))), this.internalIsPublic && (index.h("div", { key: '73c72ec32b5fdd74e333594d37aa9601ce274121', class: "share-section" }, index.h("div", { key: 'f7cf9d1f4c1680ed35c0751df8abf46fbaec2f52', class: "share-url-container" }, index.h("input", { key: '971c49e294ecf0d95854f54a42b1d45c6bd2c3ae', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), index.h("button", { key: 'ff40fb3e0cc45b5b9d99b0b7f0ff7c3939f7ecb6', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? 'Copied!' : 'Copy link' }, index.h("kritzel-icon", { key: 'b299bb0c2a03f5522134f5b3cee5de6cc1d4df5d', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
29415
+ : '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 })))))))));
29363
29416
  }
29364
29417
  static get watchers() { return {
29365
29418
  "isPublic": [{
@@ -29907,7 +29960,7 @@ const KritzelUtilityPanel = class {
29907
29960
  this.redo.emit();
29908
29961
  }
29909
29962
  render() {
29910
- return (index.h(index.Host, { key: 'b49f6db6c0e574dc8a5a733c749ecda6f24f9d25' }, index.h("button", { key: 'f65be4fff352b55087f9cb880b9139802b4969e6', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event) }, index.h("kritzel-icon", { key: 'd58906a4f105923237a98fe2e6b16a53dcccc3f6', name: "undo" })), index.h("button", { key: '2b7cf2235902920d6b18fe76d0ba2d1d70e4b2c8', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event) }, index.h("kritzel-icon", { key: '9588ded274449358024e16e8783d30ef451a3a7c', name: "redo" })), index.h("div", { key: '6ab6db05e2ec35aa59524c41ccb7b339819c9d14', class: "utility-separator" }), index.h("button", { key: '0eb06eebbda95cebc4ea932b9ec45b2c06324f80', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit() }, index.h("kritzel-icon", { key: '10b51caad06e0a7489c6ef7155073891edad4b63', name: "delete" }))));
29963
+ return (index.h(index.Host, { key: 'f800ea5843cf73ae132b56396ad05d664043f789' }, index.h("button", { key: 'd5dd4dc6e91c106eced7551c02d5f12a915b1d22', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event) }, index.h("kritzel-icon", { key: '64ac3c8f118c991b50dc99e70d4b952fc759c958', name: "undo" })), index.h("button", { key: '97a8d694fd999eb505fdcdb532d4476ce369e60d', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event) }, index.h("kritzel-icon", { key: 'ba22d5c6b246967b00112dc2efeb26920187d88f', name: "redo" })), index.h("div", { key: 'a4aa6a3202640742826d2217f2bbae9ebd2b84da', class: "utility-separator" }), index.h("button", { key: '1de2a896a6a70c22f9fa16a21af10f07f4b0303a', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit() }, index.h("kritzel-icon", { key: '202612645c1a3e8ee7e4cc01a0305d4e673874e4', name: "delete" }))));
29911
29964
  }
29912
29965
  };
29913
29966
  KritzelUtilityPanel.style = kritzelUtilityPanelCss();
@@ -14511,6 +14511,10 @@ const lightTheme = {
14511
14511
  },
14512
14512
  engine: {
14513
14513
  backgroundColor: '#ffffff',
14514
+ loadingOverlayBackground: 'rgba(255, 255, 255, 0.85)',
14515
+ loadingOverlayColor: '#333333',
14516
+ loadingOverlaySpinnerActiveColor: '#333333',
14517
+ loadingOverlaySpinnerColor: '#cccccc',
14514
14518
  },
14515
14519
  snap: {
14516
14520
  indicatorFill: 'rgba(59, 130, 246, 0.3)',
@@ -14780,6 +14784,10 @@ const darkTheme = {
14780
14784
  },
14781
14785
  engine: {
14782
14786
  backgroundColor: '#1a1a1a',
14787
+ loadingOverlayBackground: 'rgba(26, 26, 26, 0.85)',
14788
+ loadingOverlayColor: '#e0e0e0',
14789
+ loadingOverlaySpinnerActiveColor: '#e0e0e0',
14790
+ loadingOverlaySpinnerColor: '#555555',
14783
14791
  },
14784
14792
  snap: {
14785
14793
  indicatorFill: 'rgba(10, 132, 255, 0.35)',
@@ -19671,6 +19679,7 @@ class KritzelBrushTool extends KritzelBaseTool {
19671
19679
  }
19672
19680
  this._core.store.objects?.setActiveDrawingObject(null);
19673
19681
  this._currentPathId = null;
19682
+ this._core.store.objects?.stopUndoCapturing();
19674
19683
  }
19675
19684
  }
19676
19685
  }
@@ -19687,6 +19696,7 @@ class KritzelBrushTool extends KritzelBaseTool {
19687
19696
  }
19688
19697
  this._core.store.objects?.setActiveDrawingObject(null);
19689
19698
  this._currentPathId = null;
19699
+ this._core.store.objects?.stopUndoCapturing();
19690
19700
  }
19691
19701
  }
19692
19702
  }
@@ -20518,6 +20528,7 @@ class KritzelLineTool extends KritzelBaseTool {
20518
20528
  }
20519
20529
  this._core.store.objects?.setActiveDrawingObject(null);
20520
20530
  this._currentLineId = null;
20531
+ this._core.store.objects?.stopUndoCapturing();
20521
20532
  }
20522
20533
  }
20523
20534
  }
@@ -20536,6 +20547,7 @@ class KritzelLineTool extends KritzelBaseTool {
20536
20547
  }
20537
20548
  this._core.store.objects?.setActiveDrawingObject(null);
20538
20549
  this._currentLineId = null;
20550
+ this._core.store.objects?.stopUndoCapturing();
20539
20551
  }
20540
20552
  }
20541
20553
  }
@@ -20642,17 +20654,24 @@ class KritzelEraserTool extends KritzelBaseTool {
20642
20654
  if (event.pointerType === 'mouse') {
20643
20655
  if (this._core.store.state.isErasing) {
20644
20656
  const objectsToRemove = this._core.store.allObjects.filter(object => object.markedForRemoval);
20645
- objectsToRemove.forEach(object => {
20646
- object.markedForRemoval = false;
20647
- this._core.removeObject(object);
20648
- });
20649
20657
  if (objectsToRemove.length > 0) {
20658
+ // Seal the previous undo step so create+delete of the same object
20659
+ // (e.g. just-drawn shape) don't collapse into a no-op on undo.
20660
+ this._core.store.objects.stopUndoCapturing();
20661
+ // Group all removals from this sweep into a single undo step.
20662
+ this._core.store.objects.transaction(() => {
20663
+ objectsToRemove.forEach(object => {
20664
+ object.markedForRemoval = false;
20665
+ this._core.removeObject(object);
20666
+ });
20667
+ });
20650
20668
  this._core.rerender();
20651
20669
  }
20652
20670
  this._core.store.state.isErasing = false;
20653
20671
  this._core.engine.emitObjectsChange();
20654
20672
  if (objectsToRemove.length > 0) {
20655
20673
  this._core.engine.emitObjectsRemoved(objectsToRemove);
20674
+ this._core.store.objects.stopUndoCapturing();
20656
20675
  }
20657
20676
  }
20658
20677
  }
@@ -20660,17 +20679,24 @@ class KritzelEraserTool extends KritzelBaseTool {
20660
20679
  clearTimeout(this.touchStartTimeout);
20661
20680
  if (this._core.store.state.isErasing) {
20662
20681
  const objectsToRemove = this._core.store.allObjects.filter(object => object.markedForRemoval);
20663
- objectsToRemove.forEach(object => {
20664
- object.markedForRemoval = false;
20665
- this._core.removeObject(object);
20666
- });
20667
20682
  if (objectsToRemove.length > 0) {
20683
+ // Seal the previous undo step so create+delete of the same object
20684
+ // (e.g. just-drawn shape) don't collapse into a no-op on undo.
20685
+ this._core.store.objects.stopUndoCapturing();
20686
+ // Group all removals from this sweep into a single undo step.
20687
+ this._core.store.objects.transaction(() => {
20688
+ objectsToRemove.forEach(object => {
20689
+ object.markedForRemoval = false;
20690
+ this._core.removeObject(object);
20691
+ });
20692
+ });
20668
20693
  this._core.rerender();
20669
20694
  }
20670
20695
  this._core.store.state.isErasing = false;
20671
20696
  this._core.engine.emitObjectsChange();
20672
20697
  if (objectsToRemove.length > 0) {
20673
20698
  this._core.engine.emitObjectsRemoved(objectsToRemove);
20699
+ this._core.store.objects.stopUndoCapturing();
20674
20700
  }
20675
20701
  }
20676
20702
  }
@@ -21275,6 +21301,7 @@ class KritzelShapeTool extends KritzelBaseTool {
21275
21301
  this.isDrawing = false;
21276
21302
  this._core.store.objects?.setActiveDrawingObject(null);
21277
21303
  this.currentShape = null;
21304
+ this._core.store.objects?.stopUndoCapturing();
21278
21305
  this._core.rerender();
21279
21306
  }
21280
21307
  }
@@ -21684,6 +21711,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
21684
21711
  this._core.store.selectionGroup.update();
21685
21712
  this._core.engine.emitObjectsChange();
21686
21713
  this._core.store.state.hasObjectsChanged = true;
21714
+ this._core.store.objects.stopUndoCapturing();
21687
21715
  }
21688
21716
  }
21689
21717
  }
@@ -21695,6 +21723,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
21695
21723
  this._core.store.selectionGroup.update();
21696
21724
  this._core.engine.emitObjectsChange();
21697
21725
  this._core.store.state.hasObjectsChanged = true;
21726
+ this._core.store.objects.stopUndoCapturing();
21698
21727
  }
21699
21728
  }
21700
21729
  }
@@ -22047,6 +22076,7 @@ class KritzelResizeHandler extends KritzelBaseHandler {
22047
22076
  this._core.store.selectionGroup.update();
22048
22077
  this._core.engine.emitObjectsChange();
22049
22078
  this._core.store.state.hasObjectsChanged = true;
22079
+ this._core.store.objects.stopUndoCapturing();
22050
22080
  }
22051
22081
  this.reset();
22052
22082
  }
@@ -22058,6 +22088,7 @@ class KritzelResizeHandler extends KritzelBaseHandler {
22058
22088
  this._core.store.selectionGroup.update();
22059
22089
  this._core.engine.emitObjectsChange();
22060
22090
  this._core.store.state.hasObjectsChanged = true;
22091
+ this._core.store.objects.stopUndoCapturing();
22061
22092
  }
22062
22093
  this.reset();
22063
22094
  const timeout = this._core.store.state.longTouchTimeout;
@@ -22209,6 +22240,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
22209
22240
  this._core.engine.emitObjectsChange();
22210
22241
  this._core.store.state.isRotating = false;
22211
22242
  this._core.store.state.hasObjectsChanged = true;
22243
+ this._core.store.objects.stopUndoCapturing();
22212
22244
  this.reset();
22213
22245
  }
22214
22246
  }
@@ -22218,6 +22250,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
22218
22250
  this._core.engine.emitObjectsChange();
22219
22251
  this._core.store.state.isRotating = false;
22220
22252
  this._core.store.state.hasObjectsChanged = true;
22253
+ this._core.store.objects.stopUndoCapturing();
22221
22254
  this.reset();
22222
22255
  const timeout = this._core.store.state.longTouchTimeout;
22223
22256
  if (timeout) {
@@ -23235,6 +23268,7 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
23235
23268
  this._core.engine.emitObjectsChange();
23236
23269
  this._core.store.state.hasObjectsChanged = true;
23237
23270
  }
23271
+ this._core.store.objects.stopUndoCapturing();
23238
23272
  }
23239
23273
  this._core.store.state.isLineHandleDragging = false;
23240
23274
  this.reset();
@@ -587,8 +587,15 @@ export class KritzelCore {
587
587
  if (!selectionGroup) {
588
588
  return;
589
589
  }
590
- selectionGroup.objects.forEach(obj => this.removeObject(obj));
591
- this.removeSelectionGroup();
590
+ // Seal the selection group's creation into its own undo step so Yjs
591
+ // doesn't collapse create+delete of the SG into a no-op on undo.
592
+ this._store.objects.stopUndoCapturing();
593
+ this._store.objects.transaction(() => {
594
+ selectionGroup.objects.forEach(obj => this.removeObject(obj));
595
+ this.removeSelectionGroup();
596
+ });
597
+ // Close the deletion step so subsequent unrelated changes start a new step.
598
+ this._store.objects.stopUndoCapturing();
592
599
  this.engine.emitObjectsInViewportChange();
593
600
  this.rerender();
594
601
  }
@@ -439,6 +439,7 @@ export class KritzelLineHandleHandler extends KritzelBaseHandler {
439
439
  this._core.engine.emitObjectsChange();
440
440
  this._core.store.state.hasObjectsChanged = true;
441
441
  }
442
+ this._core.store.objects.stopUndoCapturing();
442
443
  }
443
444
  this._core.store.state.isLineHandleDragging = false;
444
445
  this.reset();
@@ -214,6 +214,7 @@ export class KritzelMoveHandler extends KritzelBaseHandler {
214
214
  this._core.store.selectionGroup.update();
215
215
  this._core.engine.emitObjectsChange();
216
216
  this._core.store.state.hasObjectsChanged = true;
217
+ this._core.store.objects.stopUndoCapturing();
217
218
  }
218
219
  }
219
220
  }
@@ -225,6 +226,7 @@ export class KritzelMoveHandler extends KritzelBaseHandler {
225
226
  this._core.store.selectionGroup.update();
226
227
  this._core.engine.emitObjectsChange();
227
228
  this._core.store.state.hasObjectsChanged = true;
229
+ this._core.store.objects.stopUndoCapturing();
228
230
  }
229
231
  }
230
232
  }
@@ -280,6 +280,7 @@ export class KritzelResizeHandler extends KritzelBaseHandler {
280
280
  this._core.store.selectionGroup.update();
281
281
  this._core.engine.emitObjectsChange();
282
282
  this._core.store.state.hasObjectsChanged = true;
283
+ this._core.store.objects.stopUndoCapturing();
283
284
  }
284
285
  this.reset();
285
286
  }
@@ -291,6 +292,7 @@ export class KritzelResizeHandler extends KritzelBaseHandler {
291
292
  this._core.store.selectionGroup.update();
292
293
  this._core.engine.emitObjectsChange();
293
294
  this._core.store.state.hasObjectsChanged = true;
295
+ this._core.store.objects.stopUndoCapturing();
294
296
  }
295
297
  this.reset();
296
298
  const timeout = this._core.store.state.longTouchTimeout;
@@ -140,6 +140,7 @@ export class KritzelRotationHandler extends KritzelBaseHandler {
140
140
  this._core.engine.emitObjectsChange();
141
141
  this._core.store.state.isRotating = false;
142
142
  this._core.store.state.hasObjectsChanged = true;
143
+ this._core.store.objects.stopUndoCapturing();
143
144
  this.reset();
144
145
  }
145
146
  }
@@ -149,6 +150,7 @@ export class KritzelRotationHandler extends KritzelBaseHandler {
149
150
  this._core.engine.emitObjectsChange();
150
151
  this._core.store.state.isRotating = false;
151
152
  this._core.store.state.hasObjectsChanged = true;
153
+ this._core.store.objects.stopUndoCapturing();
152
154
  this.reset();
153
155
  const timeout = this._core.store.state.longTouchTimeout;
154
156
  if (timeout) {