kritzel-stencil 0.1.15 → 0.1.17

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 (83) hide show
  1. package/dist/cjs/{default-line-tool.config-DuwiflC4.js → default-line-tool.config-D-Ru2SSK.js} +136 -130
  2. package/dist/cjs/index.cjs.js +1 -1
  3. package/dist/cjs/kritzel-back-to-content_32.cjs.entry.js +31 -14
  4. package/dist/collection/classes/core/core.class.js +3 -0
  5. package/dist/collection/classes/handlers/move.handler.js +2 -2
  6. package/dist/collection/classes/managers/cursor.manager.js +2 -2
  7. package/dist/collection/classes/objects/base-object.class.js +7 -0
  8. package/dist/collection/classes/objects/path.class.js +27 -0
  9. package/dist/collection/classes/registries/icon-registry.class.js +1 -1
  10. package/dist/collection/classes/tools/text-tool.class.js +4 -6
  11. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +11 -5
  12. package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.css +1 -1
  13. package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js +7 -1
  14. package/dist/collection/components/ui/kritzel-tool-config/kritzel-tool-config.css +1 -1
  15. package/dist/collection/components/ui/kritzel-tool-config/kritzel-tool-config.js +4 -2
  16. package/dist/collection/constants/version.js +1 -1
  17. package/dist/collection/helpers/keyboard.helper.js +70 -10
  18. package/dist/collection/themes/dark-theme.js +0 -45
  19. package/dist/collection/themes/light-theme.js +0 -40
  20. package/dist/components/index.js +1 -1
  21. package/dist/components/kritzel-back-to-content.js +1 -1
  22. package/dist/components/kritzel-brush-style.js +1 -1
  23. package/dist/components/kritzel-color-palette.js +1 -1
  24. package/dist/components/kritzel-color.js +1 -1
  25. package/dist/components/kritzel-context-menu.js +1 -1
  26. package/dist/components/kritzel-controls.js +1 -1
  27. package/dist/components/kritzel-dropdown.js +1 -1
  28. package/dist/components/kritzel-editor.js +1 -1
  29. package/dist/components/kritzel-engine.js +1 -1
  30. package/dist/components/kritzel-export.js +1 -1
  31. package/dist/components/kritzel-font-family.js +1 -1
  32. package/dist/components/kritzel-icon.js +1 -1
  33. package/dist/components/kritzel-master-detail.js +1 -1
  34. package/dist/components/kritzel-menu-item.js +1 -1
  35. package/dist/components/kritzel-menu.js +1 -1
  36. package/dist/components/kritzel-more-menu.js +1 -1
  37. package/dist/components/kritzel-settings.js +1 -1
  38. package/dist/components/kritzel-split-button.js +1 -1
  39. package/dist/components/kritzel-stroke-size.js +1 -1
  40. package/dist/components/kritzel-tool-config.js +1 -1
  41. package/dist/components/kritzel-utility-panel.js +1 -1
  42. package/dist/components/kritzel-workspace-manager.js +1 -1
  43. package/dist/components/p--Bo4GaCK.js +1 -0
  44. package/dist/components/{p-CYPjUjdI.js → p-B8IOGWhN.js} +1 -1
  45. package/dist/components/{p-DRXq8ybi.js → p-BDFu1vsS.js} +1 -1
  46. package/dist/components/{p-hIj0tNZB.js → p-BGwkUUZk.js} +1 -1
  47. package/dist/components/{p-BXNQ6L9k.js → p-C9HB5kJ3.js} +1 -1
  48. package/dist/components/{p-B5R3r6_m.js → p-CmqXj79q.js} +1 -1
  49. package/dist/components/p-Cpb-fnoO.js +1 -0
  50. package/dist/components/{p-CCvoXqIn.js → p-CwP7yBQP.js} +1 -1
  51. package/dist/components/p-Cy7mncoG.js +1 -0
  52. package/dist/components/p-DKDoQ9nc.js +1 -0
  53. package/dist/components/{p-CIAs81AV.js → p-DKNtjoqf.js} +1 -1
  54. package/dist/components/{p-C5flBv2m.js → p-DPR5Yq3I.js} +1 -1
  55. package/dist/components/p-DZpC1x_I.js +1 -0
  56. package/dist/components/{p-Dme4j-Ei.js → p-DgZY07rl.js} +1 -1
  57. package/dist/components/{p-BMYSfzzJ.js → p-DoE6WkDw.js} +1 -1
  58. package/dist/components/{p-NBmc8spY.js → p-DrwG_00J.js} +2 -2
  59. package/dist/components/{p-et8QBqmj.js → p-GeVIjnFi.js} +1 -1
  60. package/dist/components/{p-Cz1aTJ3F.js → p-MlG9hN-3.js} +1 -1
  61. package/dist/components/{p-ki9PrPGQ.js → p-hmtjxvkm.js} +1 -1
  62. package/dist/components/{p-BbfgUPVl.js → p-ltqCvPCv.js} +1 -1
  63. package/dist/components/{p-CinNuTeF.js → p-yWjTje8m.js} +1 -1
  64. package/dist/esm/{default-line-tool.config-CuDRR6We.js → default-line-tool.config-CYM64Io0.js} +136 -130
  65. package/dist/esm/index.js +2 -2
  66. package/dist/esm/kritzel-back-to-content_32.entry.js +31 -14
  67. package/dist/stencil/index.esm.js +1 -1
  68. package/dist/stencil/p-CYM64Io0.js +1 -0
  69. package/dist/stencil/p-e3cf8ef3.entry.js +9 -0
  70. package/dist/stencil/stencil.esm.js +1 -1
  71. package/dist/types/classes/objects/base-object.class.d.ts +5 -0
  72. package/dist/types/classes/objects/path.class.d.ts +6 -0
  73. package/dist/types/components/shared/kritzel-dropdown/kritzel-dropdown.d.ts +1 -0
  74. package/dist/types/constants/version.d.ts +1 -1
  75. package/dist/types/helpers/keyboard.helper.d.ts +1 -0
  76. package/package.json +1 -1
  77. package/dist/components/p-BqZdHh6f.js +0 -1
  78. package/dist/components/p-CKG7ycw4.js +0 -1
  79. package/dist/components/p-D9GoermT.js +0 -1
  80. package/dist/components/p-DBmK9l5y.js +0 -1
  81. package/dist/components/p-DPPpa9So.js +0 -1
  82. package/dist/stencil/p-781f1927.entry.js +0 -9
  83. package/dist/stencil/p-CuDRR6We.js +0 -1
@@ -397,6 +397,13 @@ class KritzelBaseObject {
397
397
  edit(_event) {
398
398
  // This method can be overridden by subclasses to handle edit actions.
399
399
  }
400
+ /**
401
+ * Called after properties are updated via updateObject.
402
+ * Override in subclasses to perform custom logic when specific properties change.
403
+ */
404
+ onAfterUpdate(_changedProperties) {
405
+ // Default implementation does nothing
406
+ }
400
407
  hitTest(_x, _y) {
401
408
  return true; // Default implementation, can be overridden by subclasses
402
409
  }
@@ -411,6 +418,32 @@ class KritzelBaseObject {
411
418
  }
412
419
  }
413
420
 
421
+ class KritzelDevicesHelper {
422
+ static isTouchDevice() {
423
+ return window.matchMedia('(any-pointer: coarse)').matches;
424
+ }
425
+ static isAndroid() {
426
+ return /android/i.test(navigator.userAgent);
427
+ }
428
+ static isIOS() {
429
+ return /iPad|iPhone|iPod/.test(navigator.userAgent);
430
+ }
431
+ static detectOS() {
432
+ if (this.isIOS()) {
433
+ return 'iOS';
434
+ }
435
+ else if (this.isAndroid()) {
436
+ return 'Android';
437
+ }
438
+ else {
439
+ return 'Other';
440
+ }
441
+ }
442
+ static isFirefox() {
443
+ return /firefox/i.test(navigator.userAgent);
444
+ }
445
+ }
446
+
414
447
  class KritzelKeyboardHelper {
415
448
  static forceHideKeyboard() {
416
449
  if (document.activeElement instanceof HTMLElement) {
@@ -440,49 +473,82 @@ class KritzelKeyboardHelper {
440
473
  meta.setAttribute('content', newContent);
441
474
  }
442
475
  }
476
+ static isTextInputFocused() {
477
+ const activeElement = document.activeElement;
478
+ if (!activeElement)
479
+ return false;
480
+ // Check for standard text input elements
481
+ if (activeElement instanceof HTMLInputElement) {
482
+ const textTypes = ['text', 'password', 'email', 'number', 'search', 'tel', 'url'];
483
+ return textTypes.includes(activeElement.type);
484
+ }
485
+ if (activeElement instanceof HTMLTextAreaElement) {
486
+ return true;
487
+ }
488
+ // Check for contenteditable elements
489
+ if (activeElement instanceof HTMLElement && activeElement.isContentEditable) {
490
+ return true;
491
+ }
492
+ return false;
493
+ }
443
494
  static onKeyboardVisibleChanged(callback) {
495
+ const os = KritzelDevicesHelper.detectOS();
496
+ if (os !== 'iOS' && os !== 'Android') {
497
+ return () => { };
498
+ }
499
+ // Use VirtualKeyboard API if available (modern browsers)
500
+ if ('virtualKeyboard' in navigator) {
501
+ const vk = navigator.virtualKeyboard;
502
+ const onGeometryChange = () => {
503
+ const isOpen = vk.boundingRect.height > 0;
504
+ callback(isOpen);
505
+ };
506
+ vk.addEventListener('geometrychange', onGeometryChange);
507
+ return () => vk.removeEventListener('geometrychange', onGeometryChange);
508
+ }
509
+ // Fallback: combine focus detection with viewport changes
444
510
  if ('visualViewport' in window) {
445
511
  const VIEWPORT_VS_CLIENT_HEIGHT_RATIO = 0.75;
446
- const onResize = (event) => {
447
- const target = event.target;
448
- const isOpen = (target.height * target.scale) / window.screen.height < VIEWPORT_VS_CLIENT_HEIGHT_RATIO;
512
+ let initialHeight = window.visualViewport.height;
513
+ const checkKeyboardState = () => {
514
+ const viewportRatio = (window.visualViewport.height * window.visualViewport.scale) / initialHeight;
515
+ const viewportShrunk = viewportRatio < VIEWPORT_VS_CLIENT_HEIGHT_RATIO;
516
+ const isOpen = viewportShrunk && this.isTextInputFocused();
449
517
  callback(isOpen);
450
518
  };
519
+ const onResize = () => {
520
+ checkKeyboardState();
521
+ };
522
+ const onFocusIn = () => {
523
+ // Update initial height when focus changes to capture pre-keyboard state
524
+ if (!this.isTextInputFocused()) {
525
+ initialHeight = window.visualViewport.height;
526
+ }
527
+ // Small delay to allow viewport to adjust
528
+ setTimeout(checkKeyboardState, 100);
529
+ };
530
+ const onFocusOut = () => {
531
+ // Keyboard closes when focus leaves text inputs
532
+ setTimeout(() => {
533
+ if (!this.isTextInputFocused()) {
534
+ callback(false);
535
+ // Reset initial height after keyboard closes
536
+ setTimeout(() => {
537
+ initialHeight = window.visualViewport.height;
538
+ }, 300);
539
+ }
540
+ }, 100);
541
+ };
451
542
  window.visualViewport.addEventListener('resize', onResize);
452
- return () => window.visualViewport.removeEventListener('resize', onResize);
453
- }
454
- else {
455
- // Fallback for older browsers does not provide a reliable event-based mechanism.
456
- console.warn('Listening for keyboard visibility changes is not reliably supported in this browser.');
457
- // Return a no-op cleanup function.
458
- return () => { };
459
- }
460
- }
461
- }
462
-
463
- class KritzelDevicesHelper {
464
- static isTouchDevice() {
465
- return window.matchMedia('(any-pointer: coarse)').matches;
466
- }
467
- static isAndroid() {
468
- return /android/i.test(navigator.userAgent);
469
- }
470
- static isIOS() {
471
- return /iPad|iPhone|iPod/.test(navigator.userAgent);
472
- }
473
- static detectOS() {
474
- if (this.isIOS()) {
475
- return 'iOS';
476
- }
477
- else if (this.isAndroid()) {
478
- return 'Android';
479
- }
480
- else {
481
- return 'Other';
543
+ document.addEventListener('focusin', onFocusIn);
544
+ document.addEventListener('focusout', onFocusOut);
545
+ return () => {
546
+ window.visualViewport.removeEventListener('resize', onResize);
547
+ document.removeEventListener('focusin', onFocusIn);
548
+ document.removeEventListener('focusout', onFocusOut);
549
+ };
482
550
  }
483
- }
484
- static isFirefox() {
485
- return /firefox/i.test(navigator.userAgent);
551
+ return () => { };
486
552
  }
487
553
  }
488
554
 
@@ -14089,7 +14155,6 @@ const lightTheme = {
14089
14155
  dividerColor: '#e0e0e0',
14090
14156
  focusColor: '#007acc',
14091
14157
  focusRingColor: 'rgba(0, 122, 255, 0.3)',
14092
- pointerCursor: 'pointer',
14093
14158
  hoverBackground: 'hsl(0, 0%, 0%, 4.3%)',
14094
14159
  iconColor: 'currentColor',
14095
14160
  scrollbarThumbColor: '#ebebeb',
@@ -14120,17 +14185,11 @@ const lightTheme = {
14120
14185
  contextMenu: {
14121
14186
  backgroundColor: '#ffffff',
14122
14187
  border: '1px solid #ebebeb',
14123
- borderRadius: '12px',
14124
14188
  boxShadow: '0 1px 6px rgba(0, 0, 0, 0.12)',
14125
14189
  itemActiveBackgroundColor: 'hsl(0, 0%, 0%, 8.6%)',
14126
- itemBorderRadius: '12px',
14127
14190
  itemColor: '#333333',
14128
14191
  itemDisabledColor: '#aaaaaa',
14129
- itemFontSize: '14px',
14130
- itemGap: '8px',
14131
14192
  itemHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14132
- itemPadding: '8px',
14133
- padding: '4px',
14134
14193
  },
14135
14194
  controls: {
14136
14195
  backgroundColor: '#ffffff',
@@ -14163,16 +14222,6 @@ const lightTheme = {
14163
14222
  selectedBackgroundColor: '#007bff1a',
14164
14223
  textColor: '#333333',
14165
14224
  },
14166
- editor: {
14167
- controlsBottom: '16px',
14168
- controlsTransform: 'translateX(-50%)',
14169
- controlsTransition: 'opacity 0.2s ease',
14170
- controlsTransitionDuration: '0.2s',
14171
- topLeftButtonsLeft: '16px',
14172
- topLeftButtonsTop: '16px',
14173
- topRightButtonsRight: '16px',
14174
- topRightButtonsTop: '16px',
14175
- },
14176
14225
  engine: {
14177
14226
  backgroundColor: '#ffffff',
14178
14227
  },
@@ -14208,27 +14257,17 @@ const lightTheme = {
14208
14257
  menu: {
14209
14258
  backgroundColor: '#ffffff',
14210
14259
  border: '1px solid #ebebeb',
14211
- borderRadius: '12px',
14212
14260
  boxShadow: '0 0 3px rgba(0, 0, 0, 0.08)',
14213
- gap: '4px',
14214
- itemBorderRadius: '12px',
14215
14261
  itemButtonHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14216
14262
  itemChildOpenBackgroundColor: 'hsl(0, 0%, 0%, 3%)',
14217
14263
  itemColor: '#333333',
14218
14264
  itemEditingBackgroundColor: '#f0f0f0',
14219
- itemFontSize: '14px',
14220
- itemHeight: '40px',
14221
14265
  itemInputBorder: '1px solid #ccc',
14222
- itemInputHeight: '32px',
14223
14266
  itemInputSelectionColor: 'rgba(255, 255, 255, 0.16)',
14224
14267
  itemInputSelectionTextColor: '#000000',
14225
- itemMinHeight: '40px',
14226
14268
  itemOverlayBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14227
- itemPadding: '8px',
14228
14269
  itemSelectedBackgroundColor: '#007aff',
14229
14270
  itemSelectedColor: '#ffffff',
14230
- padding: '8px',
14231
- width: '200px',
14232
14271
  },
14233
14272
  moreMenu: {
14234
14273
  buttonActiveBackgroundColor: '#e9e9e9',
@@ -14257,9 +14296,6 @@ const lightTheme = {
14257
14296
  thumbColor: '#ffffff',
14258
14297
  trackColor: '#e0e0e0',
14259
14298
  },
14260
- portal: {
14261
- maxHeight: '300px',
14262
- },
14263
14299
  settings: {
14264
14300
  contentHeadingColor: '#000000',
14265
14301
  contentTextColor: '#333333',
@@ -14272,14 +14308,10 @@ const lightTheme = {
14272
14308
  selectedBackgroundColor: '#ebebeb',
14273
14309
  },
14274
14310
  slideToggle: {
14275
- borderRadius: '11px',
14276
- height: '22px',
14277
14311
  thumbColor: '#fff',
14278
14312
  thumbSize: '18px',
14279
14313
  trackCheckedColor: '#007AFF',
14280
14314
  trackColor: '#ccc',
14281
- transitionDuration: '0.2s',
14282
- width: '40px',
14283
14315
  },
14284
14316
  splitButton: {
14285
14317
  backgroundColor: '#ffffff',
@@ -14293,20 +14325,14 @@ const lightTheme = {
14293
14325
  hoverBackgroundColor: '#ebebeb',
14294
14326
  selectedBackgroundColor: '#ebebeb',
14295
14327
  },
14296
- submenu: {
14297
- gap: '4px',
14298
- },
14299
14328
  tooltip: {
14300
14329
  backgroundColor: '#ffffff',
14301
14330
  border: '1px solid #ebebeb',
14302
- borderRadius: '16px',
14303
14331
  boxShadow: '0 1px 6px rgba(0, 0, 0, 0.12)',
14304
14332
  color: '#000000',
14305
- padding: '12px',
14306
14333
  },
14307
14334
  utilityPanel: {
14308
14335
  backgroundColor: '#e2e2e2',
14309
- buttonBorderRadius: '8px',
14310
14336
  buttonColor: '#333333',
14311
14337
  buttonHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14312
14338
  separatorColor: 'hsl(0, 0%, 0%, 8%)',
@@ -14323,7 +14349,6 @@ const darkTheme = {
14323
14349
  dividerColor: '#3a3a3a',
14324
14350
  focusColor: '#4da3ff',
14325
14351
  focusRingColor: 'rgba(0, 122, 255, 0.4)',
14326
- pointerCursor: 'pointer',
14327
14352
  hoverBackground: 'hsl(0, 0%, 100%, 8%)',
14328
14353
  iconColor: 'currentColor',
14329
14354
  scrollbarThumbColor: '#555555',
@@ -14354,17 +14379,11 @@ const darkTheme = {
14354
14379
  contextMenu: {
14355
14380
  backgroundColor: '#2a2a2a',
14356
14381
  border: '1px solid #3a3a3a',
14357
- borderRadius: '12px',
14358
14382
  boxShadow: '0 1px 8px rgba(0, 0, 0, 0.4)',
14359
14383
  itemActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
14360
- itemBorderRadius: '12px',
14361
14384
  itemColor: '#e0e0e0',
14362
14385
  itemDisabledColor: '#666666',
14363
- itemFontSize: '14px',
14364
- itemGap: '8px',
14365
14386
  itemHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14366
- itemPadding: '8px',
14367
- padding: '4px',
14368
14387
  },
14369
14388
  controls: {
14370
14389
  backgroundColor: '#2a2a2a',
@@ -14379,9 +14398,7 @@ const darkTheme = {
14379
14398
  dialog: {
14380
14399
  backdropColor: 'rgba(0, 0, 0, 0.6)',
14381
14400
  backgroundColor: '#2a2a2a',
14382
- bodyPadding: '16px',
14383
14401
  border: '1px solid #3a3a3a',
14384
- borderRadius: '16px',
14385
14402
  boxShadow: '0 4px 24px rgba(0, 0, 0, 0.5)',
14386
14403
  closeButtonActiveBackground: 'hsl(0, 0%, 100%, 12%)',
14387
14404
  closeButtonBackground: 'transparent',
@@ -14391,8 +14408,6 @@ const darkTheme = {
14391
14408
  footerBorder: '1px solid #3a3a3a',
14392
14409
  headerBorder: '1px solid #3a3a3a',
14393
14410
  titleColor: '#ffffff',
14394
- titleFontSize: '18px',
14395
- titleFontWeight: '600',
14396
14411
  },
14397
14412
  dropdown: {
14398
14413
  accentColor: '#0A84FF',
@@ -14400,16 +14415,6 @@ const darkTheme = {
14400
14415
  selectedBackgroundColor: 'rgba(10, 132, 255, 0.2)',
14401
14416
  textColor: '#e0e0e0',
14402
14417
  },
14403
- editor: {
14404
- controlsBottom: '16px',
14405
- controlsTransform: 'translateX(-50%)',
14406
- controlsTransition: 'opacity 0.2s ease',
14407
- controlsTransitionDuration: '0.2s',
14408
- topLeftButtonsLeft: '16px',
14409
- topLeftButtonsTop: '16px',
14410
- topRightButtonsRight: '16px',
14411
- topRightButtonsTop: '16px',
14412
- },
14413
14418
  engine: {
14414
14419
  backgroundColor: '#1a1a1a',
14415
14420
  },
@@ -14445,33 +14450,22 @@ const darkTheme = {
14445
14450
  menu: {
14446
14451
  backgroundColor: '#2a2a2a',
14447
14452
  border: '1px solid #3a3a3a',
14448
- borderRadius: '12px',
14449
14453
  boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
14450
- gap: '4px',
14451
- itemBorderRadius: '12px',
14452
14454
  itemButtonHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14453
14455
  itemChildOpenBackgroundColor: 'hsl(0, 0%, 100%, 6%)',
14454
14456
  itemColor: '#e0e0e0',
14455
14457
  itemEditingBackgroundColor: '#3a3a3a',
14456
- itemFontSize: '14px',
14457
- itemHeight: '40px',
14458
14458
  itemInputBorder: '1px solid #4a4a4a',
14459
- itemInputHeight: '32px',
14460
14459
  itemInputSelectionColor: 'rgba(255, 255, 255, 0.2)',
14461
14460
  itemInputSelectionTextColor: '#ffffff',
14462
- itemMinHeight: '40px',
14463
14461
  itemOverlayBackgroundColor: 'hsl(0, 0%, 0%, 20%)',
14464
- itemPadding: '8px',
14465
14462
  itemSelectedBackgroundColor: '#0A84FF',
14466
14463
  itemSelectedColor: '#ffffff',
14467
- padding: '8px',
14468
- width: '200px',
14469
14464
  },
14470
14465
  moreMenu: {
14471
14466
  buttonActiveBackgroundColor: '#444444',
14472
14467
  buttonBackgroundColor: '#2a2a2a',
14473
14468
  buttonBorder: '1px solid #3a3a3a',
14474
- buttonBorderRadius: '12px',
14475
14469
  buttonBoxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
14476
14470
  buttonColor: '#ffffff',
14477
14471
  buttonHoverBackgroundColor: '#3b3b3b',
@@ -14494,9 +14488,6 @@ const darkTheme = {
14494
14488
  thumbColor: '#ffffff',
14495
14489
  trackColor: '#4a4a4a',
14496
14490
  },
14497
- portal: {
14498
- maxHeight: '300px',
14499
- },
14500
14491
  settings: {
14501
14492
  contentHeadingColor: '#ffffff',
14502
14493
  contentTextColor: '#e0e0e0',
@@ -14509,14 +14500,10 @@ const darkTheme = {
14509
14500
  selectedBackgroundColor: '#3a3a3a',
14510
14501
  },
14511
14502
  slideToggle: {
14512
- borderRadius: '11px',
14513
- height: '22px',
14514
14503
  thumbColor: '#ffffff',
14515
- thumbSize: '18px',
14516
14504
  trackCheckedColor: '#0A84FF',
14517
14505
  trackColor: '#4a4a4a',
14518
14506
  transitionDuration: '0.2s',
14519
- width: '40px',
14520
14507
  },
14521
14508
  splitButton: {
14522
14509
  backgroundColor: '#2a2a2a',
@@ -14530,20 +14517,14 @@ const darkTheme = {
14530
14517
  hoverBackgroundColor: '#3a3a3a',
14531
14518
  selectedBackgroundColor: '#3a3a3a',
14532
14519
  },
14533
- submenu: {
14534
- gap: '4px',
14535
- },
14536
14520
  tooltip: {
14537
14521
  backgroundColor: '#2a2a2a',
14538
14522
  border: '1px solid #3a3a3a',
14539
- borderRadius: '16px',
14540
14523
  boxShadow: '0 1px 8px rgba(0, 0, 0, 0.4)',
14541
14524
  color: '#ffffff',
14542
- padding: '12px',
14543
14525
  },
14544
14526
  utilityPanel: {
14545
14527
  backgroundColor: '#3a3a3a',
14546
- buttonBorderRadius: '8px',
14547
14528
  buttonColor: '#e0e0e0',
14548
14529
  buttonHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14549
14530
  separatorColor: 'hsl(0, 0%, 100%, 12%)',
@@ -15101,6 +15082,12 @@ class KritzelPath extends KritzelBaseObject {
15101
15082
  const scaleY = height / this.height;
15102
15083
  this.width = width;
15103
15084
  this.height = height;
15085
+ if (this.points.length === 1) {
15086
+ const p = this.points[0];
15087
+ const spreadX = Math.max(0, width - this.strokeWidth) / scaleX;
15088
+ const spreadY = Math.max(0, height - this.strokeWidth) / scaleY;
15089
+ this.points.push([p[0] + spreadX, p[1] + spreadY]);
15090
+ }
15104
15091
  this.points = this.points.map(([x, y]) => [x * scaleX, y * scaleY]);
15105
15092
  this.d = this.generateSvgPath();
15106
15093
  this.width = Math.max(...this.points.map(p => p[0])) - Math.min(...this.points.map(p => p[0])) + this.strokeWidth;
@@ -15201,6 +15188,13 @@ class KritzelPath extends KritzelBaseObject {
15201
15188
  this._adjustedPoints = null;
15202
15189
  this._core.store.state.objects.update(this);
15203
15190
  }
15191
+ onAfterUpdate(changedProperties) {
15192
+ if (changedProperties.includes('strokeWidth')) {
15193
+ this.d = this.generateSvgPath();
15194
+ this.updateBoundingBox();
15195
+ this._adjustedPoints = null;
15196
+ }
15197
+ }
15204
15198
  computeAdjustedPoints() {
15205
15199
  if (!this.points?.length) {
15206
15200
  return [];
@@ -15268,6 +15262,20 @@ class KritzelPath extends KritzelBaseObject {
15268
15262
  this.translateX = (this.x + this.translateX) / this.scale;
15269
15263
  this.translateY = (this.y + this.translateY) / this.scale;
15270
15264
  }
15265
+ /**
15266
+ * Updates width, height, x, y based on current points and strokeWidth.
15267
+ * Does NOT modify translateX/translateY (use updateDimensions for initial setup).
15268
+ */
15269
+ updateBoundingBox() {
15270
+ const minX = Math.min(...this.points.map(p => p[0])) - this.strokeWidth / 2;
15271
+ const minY = Math.min(...this.points.map(p => p[1])) - this.strokeWidth / 2;
15272
+ const maxX = Math.max(...this.points.map(p => p[0])) + this.strokeWidth / 2;
15273
+ const maxY = Math.max(...this.points.map(p => p[1])) + this.strokeWidth / 2;
15274
+ this.width = maxX - minX + this.lineSlack;
15275
+ this.height = maxY - minY + this.lineSlack;
15276
+ this.x = minX;
15277
+ this.y = minY;
15278
+ }
15271
15279
  generateSvgPath() {
15272
15280
  const stroke = this.getStrokeFromPoints(this.points, this.strokeWidth);
15273
15281
  return this.getSvgPathFromStroke(stroke);
@@ -17454,12 +17462,11 @@ class KritzelTextTool extends KritzelBaseTool {
17454
17462
  const clientY = event.clientY - this._core.store.offsetY;
17455
17463
  const viewportScale = this._core.store.state.scale;
17456
17464
  const lockScale = this._core.store.state.lockDrawingScale;
17457
- const divider = lockScale ? viewportScale : 1;
17458
17465
  const text = KritzelText.create(this._core, this.fontSize, this.fontFamily, lockScale ? 1 : viewportScale);
17459
17466
  text.fontColor = this.fontColor;
17460
17467
  text.opacity = this.opacity;
17461
- text.translateX = (clientX - this._core.store.state.translateX) / divider;
17462
- text.translateY = (clientY - this._core.store.state.translateY) / divider;
17468
+ text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
17469
+ text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
17463
17470
  text.zIndex = this._core.store.currentZIndex;
17464
17471
  this._core.store.state.objects.insert(text);
17465
17472
  this._core.rerender();
@@ -17492,12 +17499,11 @@ class KritzelTextTool extends KritzelBaseTool {
17492
17499
  const clientY = Math.round(activePointers[0].clientY - this._core.store.offsetY);
17493
17500
  const viewportScale = this._core.store.state.scale;
17494
17501
  const lockScale = this._core.store.state.lockDrawingScale;
17495
- const divider = lockScale ? viewportScale : 1;
17496
17502
  const text = KritzelText.create(this._core, this.fontSize, this.fontFamily, lockScale ? 1 : viewportScale);
17497
17503
  text.fontColor = this.fontColor;
17498
17504
  text.opacity = this.opacity;
17499
- text.translateX = (clientX - this._core.store.state.translateX) / divider;
17500
- text.translateY = (clientY - this._core.store.state.translateY) / divider;
17505
+ text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
17506
+ text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
17501
17507
  text.zIndex = this._core.store.currentZIndex;
17502
17508
  this._core.store.state.objects.insert(text);
17503
17509
  this._core.rerender();
@@ -17548,7 +17554,7 @@ KritzelIconRegistry.registerIcons({
17548
17554
  'image': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>',
17549
17555
  'chevron-down': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',
17550
17556
  'chevron-up': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>',
17551
- 'chevron-left': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-left-icon lucide-chevron-left"><path d="m15 18-6-6 6-6"/></svg>',
17557
+ 'chevron-left': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-left-icon lucide-chevron-left"><path d="m15 18-6-6 6-6"/></svg>',
17552
17558
  'chevron-right': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon lucide-chevron-right"><path d="m9 18 6-6-6-6"/></svg>',
17553
17559
  'chevrons-left': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevrons-left-icon lucide-chevrons-left"><path d="m11 17-5-5 5-5"/><path d="m18 17-5-5 5-5"/></svg>',
17554
17560
  'copy': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy-icon lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>',
@@ -17744,7 +17750,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
17744
17750
  const moveDeltaX = Math.abs(clientX - this.startX);
17745
17751
  const moveDeltaY = Math.abs(clientY - this.startY);
17746
17752
  const moveThreshold = 5;
17747
- if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
17753
+ if (this.hasMoved || moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
17748
17754
  // Check for anchor disconnect threshold on lines
17749
17755
  this.checkAndDisconnectAnchors(clientX, clientY);
17750
17756
  selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
@@ -17770,7 +17776,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
17770
17776
  const moveDeltaX = Math.abs(x - this.startX);
17771
17777
  const moveDeltaY = Math.abs(y - this.startY);
17772
17778
  const moveThreshold = 5;
17773
- if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
17779
+ if (this.hasMoved || moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
17774
17780
  clearTimeout(this._core.store.state.longTouchTimeout);
17775
17781
  // Check for anchor disconnect threshold on lines
17776
17782
  this.checkAndDisconnectAnchors(x, y);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var defaultLineTool_config = require('./default-line-tool.config-DuwiflC4.js');
3
+ var defaultLineTool_config = require('./default-line-tool.config-D-Ru2SSK.js');
4
4
 
5
5
  /**
6
6
  * BroadcastChannel sync provider for cross-tab synchronization