kritzel-stencil 0.1.14 → 0.1.16

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 (199) hide show
  1. package/dist/cjs/{default-line-tool.config-DvzIh9zU.js → default-line-tool.config-BXYWjUSM.js} +814 -116
  2. package/dist/cjs/index.cjs.js +4 -1
  3. package/dist/cjs/kritzel-back-to-content_32.cjs.entry.js +246 -151
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/stencil.cjs.js +1 -1
  6. package/dist/collection/classes/core/core.class.js +9 -0
  7. package/dist/collection/classes/handlers/line-handle.handler.js +3 -2
  8. package/dist/collection/classes/managers/cursor.manager.js +2 -2
  9. package/dist/collection/classes/managers/theme.manager.js +104 -0
  10. package/dist/collection/classes/objects/base-object.class.js +7 -0
  11. package/dist/collection/classes/objects/line.class.js +5 -3
  12. package/dist/collection/classes/objects/path.class.js +35 -3
  13. package/dist/collection/classes/objects/selection-box.class.js +2 -2
  14. package/dist/collection/classes/objects/shape.class.js +12 -11
  15. package/dist/collection/classes/objects/text.class.js +5 -4
  16. package/dist/collection/classes/registries/icon-registry.class.js +1 -1
  17. package/dist/collection/classes/tools/brush-tool.class.js +1 -1
  18. package/dist/collection/classes/tools/line-tool.class.js +3 -27
  19. package/dist/collection/classes/tools/selection-tool.class.js +6 -4
  20. package/dist/collection/classes/tools/shape-tool.class.js +5 -20
  21. package/dist/collection/classes/tools/text-tool.class.js +7 -24
  22. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +1 -1
  23. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +38 -2
  24. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +84 -27
  25. package/dist/collection/components/shared/kritzel-color/kritzel-color.css +5 -1
  26. package/dist/collection/components/shared/kritzel-color/kritzel-color.js +51 -8
  27. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.css +1 -1
  28. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +70 -17
  29. package/dist/collection/components/shared/kritzel-dialog/kritzel-dialog.css +2 -2
  30. package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.css +14 -14
  31. package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.css +1 -1
  32. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.css +1 -1
  33. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +3 -2
  34. package/dist/collection/components/shared/kritzel-line-endings/kritzel-line-endings.css +1 -1
  35. package/dist/collection/components/shared/kritzel-line-endings/kritzel-line-endings.js +3 -25
  36. package/dist/collection/components/shared/kritzel-master-detail/kritzel-master-detail.css +2 -2
  37. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.css +1 -1
  38. package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.css +6 -5
  39. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.css +1 -1
  40. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.js +1 -1
  41. package/dist/collection/components/shared/kritzel-opacity-slider/kritzel-opacity-slider.css +3 -3
  42. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +46 -1
  43. package/dist/collection/components/shared/kritzel-shape-fill/kritzel-shape-fill.css +1 -1
  44. package/dist/collection/components/shared/kritzel-shape-fill/kritzel-shape-fill.js +3 -3
  45. package/dist/collection/components/shared/kritzel-slide-toggle/kritzel-slide-toggle.css +2 -1
  46. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.css +2 -2
  47. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.css +1 -1
  48. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
  49. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.css +6 -5
  50. package/dist/collection/components/ui/kritzel-back-to-content/kritzel-back-to-content.css +1 -1
  51. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.css +1 -1
  52. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +7 -7
  53. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +45 -7
  54. package/dist/collection/components/ui/kritzel-export/kritzel-export.css +9 -13
  55. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.css +8 -8
  56. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +15 -3
  57. package/dist/collection/components/ui/kritzel-tool-config/kritzel-tool-config.js +43 -6
  58. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.css +7 -6
  59. package/dist/collection/configs/default-brush-tool.config.js +1 -1
  60. package/dist/collection/configs/default-line-tool.config.js +1 -1
  61. package/dist/collection/configs/default-shape-tool.config.js +3 -3
  62. package/dist/collection/configs/default-text-tool.config.js +1 -1
  63. package/dist/collection/constants/color-palette.constants.js +31 -24
  64. package/dist/collection/constants/version.js +1 -1
  65. package/dist/collection/helpers/color.helper.js +23 -5
  66. package/dist/collection/helpers/theme.helper.js +69 -0
  67. package/dist/collection/index.js +4 -0
  68. package/dist/collection/interfaces/theme.interface.js +1 -0
  69. package/dist/collection/themes/dark-theme.js +235 -0
  70. package/dist/collection/themes/light-theme.js +232 -0
  71. package/dist/components/index.d.ts +1 -1
  72. package/dist/components/index.js +1 -1
  73. package/dist/components/kritzel-back-to-content.js +1 -1
  74. package/dist/components/kritzel-brush-style.js +1 -1
  75. package/dist/components/kritzel-color-palette.js +1 -1
  76. package/dist/components/kritzel-color.js +1 -1
  77. package/dist/components/kritzel-context-menu.js +1 -1
  78. package/dist/components/kritzel-controls.js +1 -1
  79. package/dist/components/kritzel-dialog.js +1 -1
  80. package/dist/components/kritzel-dropdown.js +1 -1
  81. package/dist/components/kritzel-editor.js +1 -1
  82. package/dist/components/kritzel-engine.js +1 -1
  83. package/dist/components/kritzel-export.js +1 -1
  84. package/dist/components/kritzel-font-family.js +1 -1
  85. package/dist/components/kritzel-font-size.js +1 -1
  86. package/dist/components/kritzel-icon.js +1 -1
  87. package/dist/components/kritzel-line-endings.js +1 -1
  88. package/dist/components/kritzel-master-detail.js +1 -1
  89. package/dist/components/kritzel-menu-item.js +1 -1
  90. package/dist/components/kritzel-menu.js +1 -1
  91. package/dist/components/kritzel-more-menu.js +1 -1
  92. package/dist/components/kritzel-numeric-input.js +1 -1
  93. package/dist/components/kritzel-opacity-slider.js +1 -1
  94. package/dist/components/kritzel-portal.js +1 -1
  95. package/dist/components/kritzel-settings.js +1 -1
  96. package/dist/components/kritzel-shape-fill.js +1 -1
  97. package/dist/components/kritzel-slide-toggle.js +1 -1
  98. package/dist/components/kritzel-split-button.js +1 -1
  99. package/dist/components/kritzel-stroke-size.js +1 -1
  100. package/dist/components/kritzel-tool-config.js +1 -1
  101. package/dist/components/kritzel-tooltip.js +1 -1
  102. package/dist/components/kritzel-utility-panel.js +1 -1
  103. package/dist/components/kritzel-workspace-manager.js +1 -1
  104. package/dist/components/p-6USF_L1F.js +1 -0
  105. package/dist/components/p-8uzm1dKV.js +1 -0
  106. package/dist/components/p-B6L-euG3.js +1 -0
  107. package/dist/components/{p-BCZgrVsy.js → p-BGwkUUZk.js} +1 -1
  108. package/dist/components/p-BrAnZtQA.js +1 -0
  109. package/dist/components/p-Bzv0vavh.js +1 -0
  110. package/dist/components/{p-B6UZznNo.js → p-C9HB5kJ3.js} +1 -1
  111. package/dist/components/{p-DN1_B6ky.js → p-CCvoXqIn.js} +1 -1
  112. package/dist/components/p-CJTKpwmi.js +1 -0
  113. package/dist/components/{p-CIiUpoDZ.js → p-CKG7ycw4.js} +1 -1
  114. package/dist/components/{p-BtGrZ0-u.js → p-CTQmvTXG.js} +1 -1
  115. package/dist/components/p-C__BfmIJ.js +1 -0
  116. package/dist/components/p-Cpb-fnoO.js +1 -0
  117. package/dist/components/p-Cuf-GvO0.js +1 -0
  118. package/dist/components/{p-C7GNWyf2.js → p-DKNtjoqf.js} +1 -1
  119. package/dist/components/{p-CEYFDak6.js → p-DgZY07rl.js} +1 -1
  120. package/dist/components/p-DnB4Srvo.js +1 -0
  121. package/dist/components/{p-CSWxqKCC.js → p-DoE6WkDw.js} +1 -1
  122. package/dist/components/p-GeVIjnFi.js +1 -0
  123. package/dist/components/{p-C2cNCqzd.js → p-Mre0ZWEc.js} +1 -1
  124. package/dist/components/p-RU06uu0S.js +1 -0
  125. package/dist/components/p-UNc_oph8.js +1 -0
  126. package/dist/components/p-bE-Bpn0g.js +9 -0
  127. package/dist/components/p-dQFQsn5l.js +1 -0
  128. package/dist/components/p-dYHgrz6o.js +1 -0
  129. package/dist/components/p-hmtjxvkm.js +1 -0
  130. package/dist/components/p-ltqCvPCv.js +1 -0
  131. package/dist/components/{p-BG4Z2Dwn.js → p-n0XDtwWP.js} +1 -1
  132. package/dist/components/p-y6zswJUQ.js +1 -0
  133. package/dist/components/{p-DSMMwH1h.js → p-yWjTje8m.js} +1 -1
  134. package/dist/esm/{default-line-tool.config-cZLDi3SD.js → default-line-tool.config-BKFxgp0p.js} +811 -117
  135. package/dist/esm/index.js +2 -2
  136. package/dist/esm/kritzel-back-to-content_32.entry.js +246 -151
  137. package/dist/esm/loader.js +1 -1
  138. package/dist/esm/stencil.js +1 -1
  139. package/dist/stencil/index.esm.js +1 -1
  140. package/dist/stencil/p-BKFxgp0p.js +1 -0
  141. package/dist/stencil/p-afc040bc.entry.js +9 -0
  142. package/dist/stencil/stencil.esm.js +1 -1
  143. package/dist/types/classes/core/core.class.d.ts +3 -0
  144. package/dist/types/classes/managers/theme.manager.d.ts +56 -0
  145. package/dist/types/classes/objects/base-object.class.d.ts +8 -2
  146. package/dist/types/classes/objects/line.class.d.ts +2 -1
  147. package/dist/types/classes/objects/path.class.d.ts +10 -3
  148. package/dist/types/classes/objects/shape.class.d.ts +10 -9
  149. package/dist/types/classes/objects/text.class.d.ts +3 -2
  150. package/dist/types/classes/tools/brush-tool.class.d.ts +3 -2
  151. package/dist/types/classes/tools/line-tool.class.d.ts +3 -2
  152. package/dist/types/classes/tools/selection-tool.class.d.ts +6 -5
  153. package/dist/types/classes/tools/shape-tool.class.d.ts +5 -4
  154. package/dist/types/classes/tools/text-tool.class.d.ts +3 -2
  155. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +4 -0
  156. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +4 -0
  157. package/dist/types/components/shared/kritzel-color/kritzel-color.d.ts +5 -2
  158. package/dist/types/components/shared/kritzel-color-palette/kritzel-color-palette.d.ts +6 -3
  159. package/dist/types/components/shared/kritzel-line-endings/kritzel-line-endings.d.ts +0 -2
  160. package/dist/types/components/shared/kritzel-portal/kritzel-portal.d.ts +2 -0
  161. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +3 -0
  162. package/dist/types/components/ui/kritzel-settings/kritzel-settings.d.ts +4 -0
  163. package/dist/types/components/ui/kritzel-tool-config/kritzel-tool-config.d.ts +4 -1
  164. package/dist/types/components.d.ts +32 -18
  165. package/dist/types/constants/color-palette.constants.d.ts +25 -1
  166. package/dist/types/constants/version.d.ts +1 -1
  167. package/dist/types/helpers/color.helper.d.ts +14 -4
  168. package/dist/types/helpers/theme.helper.d.ts +41 -0
  169. package/dist/types/index.d.ts +4 -0
  170. package/dist/types/interfaces/arrow-head.interface.d.ts +2 -1
  171. package/dist/types/interfaces/line-options.interface.d.ts +2 -1
  172. package/dist/types/interfaces/object.interface.d.ts +3 -2
  173. package/dist/types/interfaces/path-options.interface.d.ts +3 -2
  174. package/dist/types/interfaces/settings.interface.d.ts +3 -0
  175. package/dist/types/interfaces/theme.interface.d.ts +323 -0
  176. package/dist/types/interfaces/toolbar-control.interface.d.ts +11 -10
  177. package/dist/types/themes/dark-theme.d.ts +5 -0
  178. package/dist/types/themes/light-theme.d.ts +5 -0
  179. package/package.json +1 -1
  180. package/dist/components/p-4IV4i5r-.js +0 -1
  181. package/dist/components/p-5Vxv1ZKh.js +0 -1
  182. package/dist/components/p-9VVxMmQY.js +0 -1
  183. package/dist/components/p-BdnNVYxB.js +0 -1
  184. package/dist/components/p-BhTMzfWj.js +0 -1
  185. package/dist/components/p-BtTXKrNq.js +0 -9
  186. package/dist/components/p-C40Eqc_i.js +0 -1
  187. package/dist/components/p-C8jozyvo.js +0 -1
  188. package/dist/components/p-CCiIxqPN.js +0 -1
  189. package/dist/components/p-CP3i626h.js +0 -1
  190. package/dist/components/p-CnO82wQT.js +0 -1
  191. package/dist/components/p-CpfCNRr2.js +0 -1
  192. package/dist/components/p-CuifaWTr.js +0 -1
  193. package/dist/components/p-DPPpa9So.js +0 -1
  194. package/dist/components/p-DgMrqt6e.js +0 -1
  195. package/dist/components/p-DuK31Tjt.js +0 -1
  196. package/dist/components/p-K1KgiJP8.js +0 -1
  197. package/dist/components/p-yzi-W-0P.js +0 -1
  198. package/dist/stencil/p-1e78ba5f.entry.js +0 -9
  199. package/dist/stencil/p-cZLDi3SD.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
  }
@@ -14041,11 +14048,737 @@ Depending on the detected platform, this will hold
14041
14048
  */
14042
14049
  const baseKeymap = mac ? macBaseKeymap : pcBaseKeymap;
14043
14050
 
14051
+ /**
14052
+ * Helper function to resolve a color value for a specific theme
14053
+ */
14054
+ function resolveColor(color, theme) {
14055
+ return color[theme];
14056
+ }
14057
+ /**
14058
+ * Default color palette shared across all tool configurations.
14059
+ * This ensures consistency in color options throughout the application.
14060
+ * All colors support theme-specific variations.
14061
+ */
14062
+ const DEFAULT_COLOR_PALETTE = [
14063
+ { light: '#000000', dark: '#ffffff', label: 'Primary' },
14064
+ { light: '#ff5252', dark: '#ff5252' },
14065
+ { light: '#ffbc00', dark: '#ffbc00' },
14066
+ { light: '#00c853', dark: '#00c853' },
14067
+ { light: '#0000FF', dark: '#0000FF' },
14068
+ { light: '#d500f9', dark: '#d500f9' },
14069
+ { light: '#fafafa', dark: '#212121', label: 'Background' },
14070
+ { light: '#a52714', dark: '#a52714' },
14071
+ { light: '#ee8100', dark: '#ee8100' },
14072
+ { light: '#558b2f', dark: '#558b2f' },
14073
+ { light: '#01579b', dark: '#01579b' },
14074
+ { light: '#8e24aa', dark: '#8e24aa' },
14075
+ { light: '#90a4ae', dark: '#607d8b', label: 'Neutral' },
14076
+ { light: '#ff4081', dark: '#ff4081' },
14077
+ { light: '#ff6e40', dark: '#ff6e40' },
14078
+ { light: '#aeea00', dark: '#aeea00' },
14079
+ { light: '#304ffe', dark: '#304ffe' },
14080
+ { light: '#7c4dff', dark: '#7c4dff' },
14081
+ { light: '#cfd8dc', dark: '#455a64' },
14082
+ { light: '#f8bbd0', dark: '#ec407a' },
14083
+ { light: '#ffccbc', dark: '#ff7043' },
14084
+ { light: '#f0f4c3', dark: '#c0ca33' },
14085
+ { light: '#9fa8da', dark: '#5c6bc0' },
14086
+ { light: '#d1c4e9', dark: '#9575cd' },
14087
+ ];
14088
+
14089
+ /**
14090
+ * Light theme preset - the default theme
14091
+ */
14092
+ const lightTheme = {
14093
+ name: 'light',
14094
+ global: {
14095
+ borderColor: '#ebebeb',
14096
+ dividerColor: '#e0e0e0',
14097
+ focusColor: '#007acc',
14098
+ focusRingColor: 'rgba(0, 122, 255, 0.3)',
14099
+ hoverBackground: 'hsl(0, 0%, 0%, 4.3%)',
14100
+ iconColor: 'currentColor',
14101
+ scrollbarThumbColor: '#ebebeb',
14102
+ textPrimary: '#000000',
14103
+ textSecondary: '#333333',
14104
+ },
14105
+ selection: {
14106
+ borderColor: '#007AFF',
14107
+ handleColor: '#ffffff',
14108
+ },
14109
+ checkerboard: {
14110
+ colorDark: '#cccccc',
14111
+ colorLight: '#ffffff',
14112
+ },
14113
+ backToContent: {
14114
+ activeBackgroundColor: 'hsl(0, 0%, 0%, 8.6%)',
14115
+ backgroundColor: '#ffffff',
14116
+ border: '1px solid #ebebeb',
14117
+ boxShadow: '0 0 3px rgba(0, 0, 0, 0.08)',
14118
+ color: '#000000',
14119
+ hoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14120
+ },
14121
+ colorPalette: {
14122
+ circleBorderColor: '#dddcdc',
14123
+ hoverBackgroundColor: '#ebebeb',
14124
+ selectedBackgroundColor: '#ebebeb',
14125
+ },
14126
+ contextMenu: {
14127
+ backgroundColor: '#ffffff',
14128
+ border: '1px solid #ebebeb',
14129
+ borderRadius: '12px',
14130
+ boxShadow: '0 1px 6px rgba(0, 0, 0, 0.12)',
14131
+ itemActiveBackgroundColor: 'hsl(0, 0%, 0%, 8.6%)',
14132
+ itemBorderRadius: '12px',
14133
+ itemColor: '#333333',
14134
+ itemDisabledColor: '#aaaaaa',
14135
+ itemFontSize: '14px',
14136
+ itemGap: '8px',
14137
+ itemHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14138
+ itemPadding: '8px',
14139
+ padding: '4px',
14140
+ },
14141
+ controls: {
14142
+ backgroundColor: '#ffffff',
14143
+ border: '1px solid #ebebeb',
14144
+ boxShadow: '0 0 3px rgba(0, 0, 0, 0.08)',
14145
+ controlActiveBackgroundColor: 'hsl(0, 0%, 0%, 8.6%)',
14146
+ controlColor: '#000000',
14147
+ controlHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14148
+ controlSelectedBackgroundColor: '#007AFF',
14149
+ controlSelectedColor: '#ffffff',
14150
+ },
14151
+ dialog: {
14152
+ backdropColor: 'rgba(0, 0, 0, 0.4)',
14153
+ backgroundColor: '#ffffff',
14154
+ border: '1px solid #ebebeb',
14155
+ boxShadow: '0 4px 24px rgba(0, 0, 0, 0.15)',
14156
+ closeButtonActiveBackground: 'hsl(0, 0%, 0%, 8.6%)',
14157
+ closeButtonBackground: 'transparent',
14158
+ closeButtonColor: '#333333',
14159
+ closeButtonHoverBackground: 'hsl(0, 0%, 0%, 4.3%)',
14160
+ closeButtonHoverColor: '#000000',
14161
+ fontFamily: 'inherit',
14162
+ footerBorder: '1px solid #ebebeb',
14163
+ headerBorder: '1px solid #ebebeb',
14164
+ titleColor: '#000000',
14165
+ },
14166
+ dropdown: {
14167
+ accentColor: '#007bff',
14168
+ hoverBackgroundColor: '#f0f0f0',
14169
+ selectedBackgroundColor: '#007bff1a',
14170
+ textColor: '#333333',
14171
+ },
14172
+ editor: {
14173
+ controlsBottom: '16px',
14174
+ controlsTransform: 'translateX(-50%)',
14175
+ controlsTransition: 'opacity 0.2s ease',
14176
+ controlsTransitionDuration: '0.2s',
14177
+ topLeftButtonsLeft: '16px',
14178
+ topLeftButtonsTop: '16px',
14179
+ topRightButtonsRight: '16px',
14180
+ topRightButtonsTop: '16px',
14181
+ },
14182
+ engine: {
14183
+ backgroundColor: '#ffffff',
14184
+ },
14185
+ fontSize: {
14186
+ hoverBackgroundColor: '#ebebeb',
14187
+ selectedBackgroundColor: '#ebebeb',
14188
+ textColor: '#333333',
14189
+ },
14190
+ lineEndings: {
14191
+ hoverBackgroundColor: '#ebebeb',
14192
+ labelColor: '#666666',
14193
+ optionBackground: '#ffffff',
14194
+ selectedBackgroundColor: '#ebebeb',
14195
+ },
14196
+ masterDetail: {
14197
+ backButtonColor: '#333333',
14198
+ backgroundColor: '#ffffff',
14199
+ detailBackgroundColor: '#ffffff',
14200
+ detailFocusOutline: '2px solid #007AFF',
14201
+ menuBackgroundColor: '#ffffff',
14202
+ menuBorderRight: '1px solid #ebebeb',
14203
+ menuItemActiveBackgroundColor: 'hsl(0, 0%, 0%, 8.6%)',
14204
+ menuItemBackgroundColor: 'transparent',
14205
+ menuItemChevronColor: '#aaaaaa',
14206
+ menuItemColor: '#333333',
14207
+ menuItemDisabledColor: '#aaaaaa',
14208
+ menuItemFocusOutline: '2px solid #007AFF',
14209
+ menuItemHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14210
+ menuItemSelectedBackgroundColor: '#007AFF',
14211
+ menuItemSelectedColor: '#ffffff',
14212
+ menuItemSelectedHoverBackgroundColor: '#007AFF',
14213
+ },
14214
+ menu: {
14215
+ backgroundColor: '#ffffff',
14216
+ border: '1px solid #ebebeb',
14217
+ borderRadius: '12px',
14218
+ boxShadow: '0 0 3px rgba(0, 0, 0, 0.08)',
14219
+ gap: '4px',
14220
+ itemBorderRadius: '12px',
14221
+ itemButtonHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14222
+ itemChildOpenBackgroundColor: 'hsl(0, 0%, 0%, 3%)',
14223
+ itemColor: '#333333',
14224
+ itemEditingBackgroundColor: '#f0f0f0',
14225
+ itemFontSize: '14px',
14226
+ itemHeight: '40px',
14227
+ itemInputBorder: '1px solid #ccc',
14228
+ itemInputHeight: '32px',
14229
+ itemInputSelectionColor: 'rgba(255, 255, 255, 0.16)',
14230
+ itemInputSelectionTextColor: '#000000',
14231
+ itemMinHeight: '40px',
14232
+ itemOverlayBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14233
+ itemPadding: '8px',
14234
+ itemSelectedBackgroundColor: '#007aff',
14235
+ itemSelectedColor: '#ffffff',
14236
+ padding: '8px',
14237
+ width: '200px',
14238
+ },
14239
+ moreMenu: {
14240
+ buttonActiveBackgroundColor: '#e9e9e9',
14241
+ buttonBackgroundColor: '#ffffff',
14242
+ buttonBorder: '1px solid #ebebeb',
14243
+ buttonBorderRadius: '12px',
14244
+ buttonBoxShadow: '0 0 3px rgba(0, 0, 0, 0.08)',
14245
+ buttonColor: '#000000',
14246
+ buttonHoverBackgroundColor: '#f5f5f5',
14247
+ },
14248
+ numericInput: {
14249
+ borderColor: '#ebebeb',
14250
+ focusBorderColor: '#007AFF',
14251
+ hoverBorderColor: '#ccc',
14252
+ inputBackground: '#ffffff',
14253
+ labelColor: '#666666',
14254
+ spinnerActiveBackground: 'hsl(0, 0%, 0%, 8.6%)',
14255
+ spinnerBackground: 'transparent',
14256
+ spinnerColor: '#333333',
14257
+ spinnerHoverBackground: 'hsl(0, 0%, 0%, 4.3%)',
14258
+ textColor: '#333333',
14259
+ },
14260
+ opacitySlider: {
14261
+ activeColor: '#007AFF',
14262
+ thumbBorderColor: '#007AFF',
14263
+ thumbColor: '#ffffff',
14264
+ trackColor: '#e0e0e0',
14265
+ },
14266
+ portal: {
14267
+ maxHeight: '300px',
14268
+ },
14269
+ settings: {
14270
+ contentHeadingColor: '#000000',
14271
+ contentTextColor: '#333333',
14272
+ descriptionColor: '#666666',
14273
+ labelColor: '#333333',
14274
+ },
14275
+ shapeFill: {
14276
+ hoverBackgroundColor: '#ebebeb',
14277
+ optionBackground: '#ffffff',
14278
+ selectedBackgroundColor: '#ebebeb',
14279
+ },
14280
+ slideToggle: {
14281
+ borderRadius: '11px',
14282
+ height: '22px',
14283
+ thumbColor: '#fff',
14284
+ thumbSize: '18px',
14285
+ trackCheckedColor: '#007AFF',
14286
+ trackColor: '#ccc',
14287
+ transitionDuration: '0.2s',
14288
+ width: '40px',
14289
+ },
14290
+ splitButton: {
14291
+ backgroundColor: '#ffffff',
14292
+ border: '1px solid #ebebeb',
14293
+ boxShadow: '0 0 3px rgba(0, 0, 0, 0.08)',
14294
+ color: '#000000',
14295
+ dividerBackgroundColor: '#ebebeb',
14296
+ hoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14297
+ },
14298
+ strokeSize: {
14299
+ hoverBackgroundColor: '#ebebeb',
14300
+ selectedBackgroundColor: '#ebebeb',
14301
+ },
14302
+ submenu: {
14303
+ gap: '4px',
14304
+ },
14305
+ tooltip: {
14306
+ backgroundColor: '#ffffff',
14307
+ border: '1px solid #ebebeb',
14308
+ borderRadius: '16px',
14309
+ boxShadow: '0 1px 6px rgba(0, 0, 0, 0.12)',
14310
+ color: '#000000',
14311
+ padding: '12px',
14312
+ },
14313
+ utilityPanel: {
14314
+ backgroundColor: '#e2e2e2',
14315
+ buttonBorderRadius: '8px',
14316
+ buttonColor: '#333333',
14317
+ buttonHoverBackgroundColor: 'hsl(0, 0%, 0%, 4.3%)',
14318
+ separatorColor: 'hsl(0, 0%, 0%, 8%)',
14319
+ },
14320
+ };
14321
+
14322
+ /**
14323
+ * Dark theme preset
14324
+ */
14325
+ const darkTheme = {
14326
+ name: 'dark',
14327
+ global: {
14328
+ borderColor: '#3a3a3a',
14329
+ dividerColor: '#3a3a3a',
14330
+ focusColor: '#4da3ff',
14331
+ focusRingColor: 'rgba(0, 122, 255, 0.4)',
14332
+ hoverBackground: 'hsl(0, 0%, 100%, 8%)',
14333
+ iconColor: 'currentColor',
14334
+ scrollbarThumbColor: '#555555',
14335
+ textPrimary: '#ffffff',
14336
+ textSecondary: '#e0e0e0',
14337
+ },
14338
+ selection: {
14339
+ borderColor: '#0A84FF',
14340
+ handleColor: '#1a1a1a',
14341
+ },
14342
+ checkerboard: {
14343
+ colorDark: '#4a4a4a',
14344
+ colorLight: '#3a3a3a',
14345
+ },
14346
+ backToContent: {
14347
+ activeBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
14348
+ backgroundColor: '#2a2a2a',
14349
+ border: '1px solid #3a3a3a',
14350
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
14351
+ color: '#ffffff',
14352
+ hoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14353
+ },
14354
+ colorPalette: {
14355
+ circleBorderColor: '#4a4a4a',
14356
+ hoverBackgroundColor: '#3a3a3a',
14357
+ selectedBackgroundColor: '#3a3a3a',
14358
+ },
14359
+ contextMenu: {
14360
+ backgroundColor: '#2a2a2a',
14361
+ border: '1px solid #3a3a3a',
14362
+ borderRadius: '12px',
14363
+ boxShadow: '0 1px 8px rgba(0, 0, 0, 0.4)',
14364
+ itemActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
14365
+ itemBorderRadius: '12px',
14366
+ itemColor: '#e0e0e0',
14367
+ itemDisabledColor: '#666666',
14368
+ itemFontSize: '14px',
14369
+ itemGap: '8px',
14370
+ itemHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14371
+ itemPadding: '8px',
14372
+ padding: '4px',
14373
+ },
14374
+ controls: {
14375
+ backgroundColor: '#2a2a2a',
14376
+ border: '1px solid #3a3a3a',
14377
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
14378
+ controlActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
14379
+ controlColor: '#ffffff',
14380
+ controlHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14381
+ controlSelectedBackgroundColor: '#0A84FF',
14382
+ controlSelectedColor: '#ffffff',
14383
+ },
14384
+ dialog: {
14385
+ backdropColor: 'rgba(0, 0, 0, 0.6)',
14386
+ backgroundColor: '#2a2a2a',
14387
+ bodyPadding: '16px',
14388
+ border: '1px solid #3a3a3a',
14389
+ borderRadius: '16px',
14390
+ boxShadow: '0 4px 24px rgba(0, 0, 0, 0.5)',
14391
+ closeButtonActiveBackground: 'hsl(0, 0%, 100%, 12%)',
14392
+ closeButtonBackground: 'transparent',
14393
+ closeButtonColor: '#e0e0e0',
14394
+ closeButtonHoverBackground: 'hsl(0, 0%, 100%, 8%)',
14395
+ closeButtonHoverColor: '#ffffff',
14396
+ footerBorder: '1px solid #3a3a3a',
14397
+ headerBorder: '1px solid #3a3a3a',
14398
+ titleColor: '#ffffff',
14399
+ titleFontSize: '18px',
14400
+ titleFontWeight: '600',
14401
+ },
14402
+ dropdown: {
14403
+ accentColor: '#0A84FF',
14404
+ hoverBackgroundColor: '#3a3a3a',
14405
+ selectedBackgroundColor: 'rgba(10, 132, 255, 0.2)',
14406
+ textColor: '#e0e0e0',
14407
+ },
14408
+ editor: {
14409
+ controlsBottom: '16px',
14410
+ controlsTransform: 'translateX(-50%)',
14411
+ controlsTransition: 'opacity 0.2s ease',
14412
+ controlsTransitionDuration: '0.2s',
14413
+ topLeftButtonsLeft: '16px',
14414
+ topLeftButtonsTop: '16px',
14415
+ topRightButtonsRight: '16px',
14416
+ topRightButtonsTop: '16px',
14417
+ },
14418
+ engine: {
14419
+ backgroundColor: '#1a1a1a',
14420
+ },
14421
+ fontSize: {
14422
+ hoverBackgroundColor: '#3a3a3a',
14423
+ selectedBackgroundColor: '#3a3a3a',
14424
+ textColor: '#e0e0e0',
14425
+ },
14426
+ lineEndings: {
14427
+ hoverBackgroundColor: '#3a3a3a',
14428
+ labelColor: '#999999',
14429
+ optionBackground: '#2a2a2a',
14430
+ selectedBackgroundColor: '#3a3a3a',
14431
+ },
14432
+ masterDetail: {
14433
+ backButtonColor: '#e0e0e0',
14434
+ backgroundColor: '#2a2a2a',
14435
+ detailBackgroundColor: '#2a2a2a',
14436
+ detailFocusOutline: '2px solid #0A84FF',
14437
+ menuBackgroundColor: '#2a2a2a',
14438
+ menuBorderRight: '1px solid #3a3a3a',
14439
+ menuItemActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
14440
+ menuItemBackgroundColor: 'transparent',
14441
+ menuItemChevronColor: '#666666',
14442
+ menuItemColor: '#e0e0e0',
14443
+ menuItemDisabledColor: '#666666',
14444
+ menuItemFocusOutline: '2px solid #0A84FF',
14445
+ menuItemHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14446
+ menuItemSelectedBackgroundColor: '#0A84FF',
14447
+ menuItemSelectedColor: '#ffffff',
14448
+ menuItemSelectedHoverBackgroundColor: '#0A84FF',
14449
+ },
14450
+ menu: {
14451
+ backgroundColor: '#2a2a2a',
14452
+ border: '1px solid #3a3a3a',
14453
+ borderRadius: '12px',
14454
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
14455
+ gap: '4px',
14456
+ itemBorderRadius: '12px',
14457
+ itemButtonHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14458
+ itemChildOpenBackgroundColor: 'hsl(0, 0%, 100%, 6%)',
14459
+ itemColor: '#e0e0e0',
14460
+ itemEditingBackgroundColor: '#3a3a3a',
14461
+ itemFontSize: '14px',
14462
+ itemHeight: '40px',
14463
+ itemInputBorder: '1px solid #4a4a4a',
14464
+ itemInputHeight: '32px',
14465
+ itemInputSelectionColor: 'rgba(255, 255, 255, 0.2)',
14466
+ itemInputSelectionTextColor: '#ffffff',
14467
+ itemMinHeight: '40px',
14468
+ itemOverlayBackgroundColor: 'hsl(0, 0%, 0%, 20%)',
14469
+ itemPadding: '8px',
14470
+ itemSelectedBackgroundColor: '#0A84FF',
14471
+ itemSelectedColor: '#ffffff',
14472
+ padding: '8px',
14473
+ width: '200px',
14474
+ },
14475
+ moreMenu: {
14476
+ buttonActiveBackgroundColor: '#444444',
14477
+ buttonBackgroundColor: '#2a2a2a',
14478
+ buttonBorder: '1px solid #3a3a3a',
14479
+ buttonBorderRadius: '12px',
14480
+ buttonBoxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
14481
+ buttonColor: '#ffffff',
14482
+ buttonHoverBackgroundColor: '#3b3b3b',
14483
+ },
14484
+ numericInput: {
14485
+ borderColor: '#3a3a3a',
14486
+ focusBorderColor: '#0A84FF',
14487
+ hoverBorderColor: '#4a4a4a',
14488
+ inputBackground: '#1a1a1a',
14489
+ labelColor: '#999999',
14490
+ spinnerActiveBackground: 'hsl(0, 0%, 100%, 12%)',
14491
+ spinnerBackground: 'transparent',
14492
+ spinnerColor: '#e0e0e0',
14493
+ spinnerHoverBackground: 'hsl(0, 0%, 100%, 8%)',
14494
+ textColor: '#e0e0e0',
14495
+ },
14496
+ opacitySlider: {
14497
+ activeColor: '#0A84FF',
14498
+ thumbBorderColor: '#0A84FF',
14499
+ thumbColor: '#ffffff',
14500
+ trackColor: '#4a4a4a',
14501
+ },
14502
+ portal: {
14503
+ maxHeight: '300px',
14504
+ },
14505
+ settings: {
14506
+ contentHeadingColor: '#ffffff',
14507
+ contentTextColor: '#e0e0e0',
14508
+ descriptionColor: '#999999',
14509
+ labelColor: '#e0e0e0',
14510
+ },
14511
+ shapeFill: {
14512
+ hoverBackgroundColor: '#3a3a3a',
14513
+ optionBackground: '#2a2a2a',
14514
+ selectedBackgroundColor: '#3a3a3a',
14515
+ },
14516
+ slideToggle: {
14517
+ borderRadius: '11px',
14518
+ height: '22px',
14519
+ thumbColor: '#ffffff',
14520
+ thumbSize: '18px',
14521
+ trackCheckedColor: '#0A84FF',
14522
+ trackColor: '#4a4a4a',
14523
+ transitionDuration: '0.2s',
14524
+ width: '40px',
14525
+ },
14526
+ splitButton: {
14527
+ backgroundColor: '#2a2a2a',
14528
+ border: '1px solid #3a3a3a',
14529
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
14530
+ color: '#ffffff',
14531
+ dividerBackgroundColor: '#3a3a3a',
14532
+ hoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14533
+ },
14534
+ strokeSize: {
14535
+ hoverBackgroundColor: '#3a3a3a',
14536
+ selectedBackgroundColor: '#3a3a3a',
14537
+ },
14538
+ submenu: {
14539
+ gap: '4px',
14540
+ },
14541
+ tooltip: {
14542
+ backgroundColor: '#2a2a2a',
14543
+ border: '1px solid #3a3a3a',
14544
+ borderRadius: '16px',
14545
+ boxShadow: '0 1px 8px rgba(0, 0, 0, 0.4)',
14546
+ color: '#ffffff',
14547
+ padding: '12px',
14548
+ },
14549
+ utilityPanel: {
14550
+ backgroundColor: '#3a3a3a',
14551
+ buttonBorderRadius: '8px',
14552
+ buttonColor: '#e0e0e0',
14553
+ buttonHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
14554
+ separatorColor: 'hsl(0, 0%, 100%, 12%)',
14555
+ },
14556
+ };
14557
+
14558
+ class ThemeHelper {
14559
+ /**
14560
+ * Converts a camelCase string to kebab-case.
14561
+ * @example ThemeHelper.camelToKebab('controlHoverBackgroundColor') → 'control-hover-background-color'
14562
+ * @example ThemeHelper.camelToKebab('backgroundColor') → 'background-color'
14563
+ * @example ThemeHelper.camelToKebab('gap') → 'gap'
14564
+ */
14565
+ static camelToKebab(str) {
14566
+ return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
14567
+ }
14568
+ /**
14569
+ * Recursively flattens a theme object into a map of CSS variable names to values.
14570
+ * Skips the 'name' property at the root level since it's the theme identifier, not a CSS value.
14571
+ *
14572
+ * @param theme - The theme object to flatten
14573
+ * @param prefix - The CSS variable prefix (default: '--kritzel')
14574
+ * @returns A Map of CSS variable names to their values
14575
+ *
14576
+ * @example
14577
+ * ThemeHelper.flattenThemeToVariables(lightTheme)
14578
+ * // Returns Map {
14579
+ * // '--kritzel-global-pointer-cursor' => 'pointer',
14580
+ * // '--kritzel-controls-gap' => '8px',
14581
+ * // ...
14582
+ * // }
14583
+ */
14584
+ static flattenThemeToVariables(theme, prefix = '--kritzel') {
14585
+ const variables = new Map();
14586
+ const recurse = (obj, currentPrefix, isRoot = false) => {
14587
+ for (const [key, value] of Object.entries(obj)) {
14588
+ // Skip the 'name' property at the root level
14589
+ if (isRoot && key === 'name') {
14590
+ continue;
14591
+ }
14592
+ const kebabKey = ThemeHelper.camelToKebab(key);
14593
+ const variableName = `${currentPrefix}-${kebabKey}`;
14594
+ if (typeof value === 'object' && value !== null) {
14595
+ recurse(value, variableName);
14596
+ }
14597
+ else if (typeof value === 'string') {
14598
+ variables.set(variableName, value);
14599
+ }
14600
+ }
14601
+ };
14602
+ recurse(theme, prefix, true);
14603
+ return variables;
14604
+ }
14605
+ /**
14606
+ * Applies a map of CSS variables to an HTML element.
14607
+ *
14608
+ * @param element - The target HTML element
14609
+ * @param variables - A Map of CSS variable names to values
14610
+ */
14611
+ static applyVariablesToElement(element, variables) {
14612
+ for (const [name, value] of variables) {
14613
+ element.style.setProperty(name, value);
14614
+ }
14615
+ }
14616
+ /**
14617
+ * Convenience method that flattens a theme and applies it to an element in one call.
14618
+ *
14619
+ * @param element - The target HTML element
14620
+ * @param theme - The theme object to apply
14621
+ */
14622
+ static applyThemeToElement(element, theme) {
14623
+ const variables = ThemeHelper.flattenThemeToVariables(theme);
14624
+ ThemeHelper.applyVariablesToElement(element, variables);
14625
+ }
14626
+ }
14627
+
14628
+ const THEME_STORAGE_KEY = 'kritzel-theme';
14629
+ const DEFAULT_THEME = 'light';
14630
+ /**
14631
+ * Manages theme state and application across the Kritzel editor.
14632
+ * Handles theme persistence, retrieval, and CSS variable application.
14633
+ */
14634
+ class KritzelThemeManager {
14635
+ _core;
14636
+ _currentTheme = DEFAULT_THEME;
14637
+ _targetElement = null;
14638
+ constructor(core) {
14639
+ this._core = core;
14640
+ this._currentTheme = KritzelThemeManager.getStoredTheme();
14641
+ }
14642
+ /**
14643
+ * Gets the current active theme name.
14644
+ */
14645
+ get currentTheme() {
14646
+ return this._currentTheme;
14647
+ }
14648
+ /**
14649
+ * Sets the target element where theme CSS variables will be applied.
14650
+ */
14651
+ setTargetElement(element) {
14652
+ this._targetElement = element;
14653
+ if (this._targetElement) {
14654
+ this.applyTheme(this._currentTheme);
14655
+ }
14656
+ }
14657
+ /**
14658
+ * Gets the current target element.
14659
+ */
14660
+ getTargetElement() {
14661
+ return this._targetElement;
14662
+ }
14663
+ /**
14664
+ * Gets the theme object by name.
14665
+ */
14666
+ getThemeByName(themeName) {
14667
+ return themeName === 'dark' ? darkTheme : lightTheme;
14668
+ }
14669
+ /**
14670
+ * Gets the stored theme name from localStorage.
14671
+ * Can be called statically without a manager instance.
14672
+ * @returns The stored theme name, or 'light' as default
14673
+ */
14674
+ static getStoredTheme() {
14675
+ if (typeof localStorage === 'undefined') {
14676
+ return DEFAULT_THEME;
14677
+ }
14678
+ const stored = localStorage.getItem(THEME_STORAGE_KEY);
14679
+ if (stored === 'dark' || stored === 'light') {
14680
+ return stored;
14681
+ }
14682
+ return DEFAULT_THEME;
14683
+ }
14684
+ /**
14685
+ * Saves the theme name to localStorage.
14686
+ */
14687
+ saveTheme(themeName) {
14688
+ if (typeof localStorage === 'undefined') {
14689
+ return;
14690
+ }
14691
+ localStorage.setItem(THEME_STORAGE_KEY, themeName);
14692
+ }
14693
+ /**
14694
+ * Sets the current theme, saves it to storage, and applies it to the target element.
14695
+ */
14696
+ setTheme(themeName) {
14697
+ this._currentTheme = themeName;
14698
+ this.saveTheme(themeName);
14699
+ if (this._targetElement) {
14700
+ this.applyTheme(themeName);
14701
+ }
14702
+ }
14703
+ /**
14704
+ * Checks if the current theme is dark.
14705
+ */
14706
+ isDarkTheme() {
14707
+ return this._currentTheme === 'dark';
14708
+ }
14709
+ /**
14710
+ * Applies a theme to the target element by setting CSS custom properties.
14711
+ * Uses the generic theme utility to automatically derive CSS variable names
14712
+ * from the theme interface structure.
14713
+ */
14714
+ applyTheme(themeName) {
14715
+ if (!this._targetElement) {
14716
+ return;
14717
+ }
14718
+ const theme = this.getThemeByName(themeName);
14719
+ ThemeHelper.applyThemeToElement(this._targetElement, theme);
14720
+ }
14721
+ /**
14722
+ * Cleans up theme manager state.
14723
+ */
14724
+ cleanup() {
14725
+ this._targetElement = null;
14726
+ }
14727
+ }
14728
+
14729
+ class KritzelColorHelper {
14730
+ /**
14731
+ * Resolves a color value based on the current theme.
14732
+ * Handles both simple string colors and theme-aware color objects.
14733
+ * @param color - The color to resolve (string or ThemeAwareColor)
14734
+ * @param theme - Optional theme to use. If not provided, uses current theme from ThemeManager
14735
+ * @returns The resolved hex color string, or empty string if color is undefined
14736
+ */
14737
+ static resolveThemeColor(color, theme) {
14738
+ if (!color) {
14739
+ return '';
14740
+ }
14741
+ const currentTheme = theme ?? KritzelThemeManager.getStoredTheme();
14742
+ return resolveColor(color, currentTheme);
14743
+ }
14744
+ /**
14745
+ * Applies opacity to a theme-aware color and returns an rgba string.
14746
+ * @param color - The theme-aware color object
14747
+ * @param opacity - The opacity value between 0 and 1
14748
+ * @param theme - Optional theme to use. If not provided, uses current theme from ThemeManager
14749
+ * @returns The color as an rgba string, or the resolved hex if opacity is 1
14750
+ */
14751
+ static applyOpacity(color, opacity, theme) {
14752
+ const hexColor = this.resolveThemeColor(color, theme);
14753
+ if (!hexColor || opacity >= 1)
14754
+ return hexColor;
14755
+ const sanitizedHex = hexColor.startsWith('#') ? hexColor.slice(1) : hexColor;
14756
+ let r, g, b;
14757
+ if (sanitizedHex.length === 3) {
14758
+ r = parseInt(sanitizedHex[0] + sanitizedHex[0], 16);
14759
+ g = parseInt(sanitizedHex[1] + sanitizedHex[1], 16);
14760
+ b = parseInt(sanitizedHex[2] + sanitizedHex[2], 16);
14761
+ }
14762
+ else if (sanitizedHex.length === 6) {
14763
+ r = parseInt(sanitizedHex.substring(0, 2), 16);
14764
+ g = parseInt(sanitizedHex.substring(2, 4), 16);
14765
+ b = parseInt(sanitizedHex.substring(4, 6), 16);
14766
+ }
14767
+ else {
14768
+ return hexColor;
14769
+ }
14770
+ if (isNaN(r) || isNaN(g) || isNaN(b)) {
14771
+ return hexColor;
14772
+ }
14773
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`;
14774
+ }
14775
+ }
14776
+
14044
14777
  class KritzelText extends KritzelBaseObject {
14045
14778
  __class__ = 'KritzelText';
14046
14779
  fontFamily = 'Arial';
14047
14780
  fontSize = 8;
14048
- fontColor = '#000000';
14781
+ fontColor = { light: '#000000', dark: '#ffffff' };
14049
14782
  initialWidth = 1;
14050
14783
  initialHeight = 1;
14051
14784
  scale = 1;
@@ -14079,7 +14812,7 @@ class KritzelText extends KritzelBaseObject {
14079
14812
  this.translateY = config.translateY || 0;
14080
14813
  this.fontSize = config.fontSize || 8;
14081
14814
  this.fontFamily = config.fontFamily || 'Arial';
14082
- this.fontColor = config.fontColor || '#000000';
14815
+ this.fontColor = config.fontColor || { light: '#000000', dark: '#ffffff' };
14083
14816
  this.width = this.initialWidth / (this._core.store.state.scale < 0 ? this._core.store.state.scale : 1);
14084
14817
  this.height = (this.fontSize * 1.2) / (this._core.store.state.scale < 0 ? this._core.store.state.scale : 1);
14085
14818
  this.scale = config.scale || 1;
@@ -14097,7 +14830,7 @@ class KritzelText extends KritzelBaseObject {
14097
14830
  object.translateY = 0;
14098
14831
  object.width = object.initialWidth / (object._core.store.state.scale < 0 ? object._core.store.state.scale : 1);
14099
14832
  object.height = (object.fontSize * 1.2) / (object._core.store.state.scale < 0 ? object._core.store.state.scale : 1);
14100
- object.backgroundColor = 'transparent';
14833
+ object.backgroundColor = { light: 'transparent', dark: 'transparent' };
14101
14834
  object.initialWidth = object.width;
14102
14835
  object.initialHeight = object.height;
14103
14836
  object.scaleFactor = 1;
@@ -14112,7 +14845,7 @@ class KritzelText extends KritzelBaseObject {
14112
14845
  }
14113
14846
  element.style.fontFamily = this.fontFamily;
14114
14847
  element.style.fontSize = `${this.fontSize}pt`;
14115
- element.style.color = this.fontColor;
14848
+ element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
14116
14849
  if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
14117
14850
  requestAnimationFrame(() => this.adjustSizeOnInput());
14118
14851
  return;
@@ -14318,7 +15051,7 @@ class KritzelPath extends KritzelBaseObject {
14318
15051
  __class__ = 'KritzelPath';
14319
15052
  points;
14320
15053
  d;
14321
- stroke = 'none';
15054
+ stroke = { light: 'none', dark: 'none' };
14322
15055
  strokeWidth;
14323
15056
  lineSlack = 0.5;
14324
15057
  fill;
@@ -14343,7 +15076,7 @@ class KritzelPath extends KritzelBaseObject {
14343
15076
  this.translateY = config?.translateY ?? 0;
14344
15077
  this.scale = config?.scale ?? 1;
14345
15078
  this.strokeWidth = config?.strokeWidth ?? 8;
14346
- this.fill = config?.fill ?? '#000000';
15079
+ this.fill = config?.fill ?? { light: '#000000', dark: '#ffffff' };
14347
15080
  this.d = this.generateSvgPath();
14348
15081
  this.updateDimensions();
14349
15082
  }
@@ -14358,7 +15091,7 @@ class KritzelPath extends KritzelBaseObject {
14358
15091
  object.translateY = options?.translateY ?? 0;
14359
15092
  object.scale = options?.scale ?? 1;
14360
15093
  object.strokeWidth = options?.strokeWidth ?? 8;
14361
- object.fill = options?.fill ?? '#000000';
15094
+ object.fill = options?.fill ?? { light: '#000000', dark: '#ffffff' };
14362
15095
  object.opacity = options?.opacity ?? 1;
14363
15096
  object.zIndex = core.store.currentZIndex;
14364
15097
  object.d = object.generateSvgPath();
@@ -14373,6 +15106,12 @@ class KritzelPath extends KritzelBaseObject {
14373
15106
  const scaleY = height / this.height;
14374
15107
  this.width = width;
14375
15108
  this.height = height;
15109
+ if (this.points.length === 1) {
15110
+ const p = this.points[0];
15111
+ const spreadX = Math.max(0, width - this.strokeWidth) / scaleX;
15112
+ const spreadY = Math.max(0, height - this.strokeWidth) / scaleY;
15113
+ this.points.push([p[0] + spreadX, p[1] + spreadY]);
15114
+ }
14376
15115
  this.points = this.points.map(([x, y]) => [x * scaleX, y * scaleY]);
14377
15116
  this.d = this.generateSvgPath();
14378
15117
  this.width = Math.max(...this.points.map(p => p[0])) - Math.min(...this.points.map(p => p[0])) + this.strokeWidth;
@@ -14473,6 +15212,13 @@ class KritzelPath extends KritzelBaseObject {
14473
15212
  this._adjustedPoints = null;
14474
15213
  this._core.store.state.objects.update(this);
14475
15214
  }
15215
+ onAfterUpdate(changedProperties) {
15216
+ if (changedProperties.includes('strokeWidth')) {
15217
+ this.d = this.generateSvgPath();
15218
+ this.updateBoundingBox();
15219
+ this._adjustedPoints = null;
15220
+ }
15221
+ }
14476
15222
  computeAdjustedPoints() {
14477
15223
  if (!this.points?.length) {
14478
15224
  return [];
@@ -14540,6 +15286,25 @@ class KritzelPath extends KritzelBaseObject {
14540
15286
  this.translateX = (this.x + this.translateX) / this.scale;
14541
15287
  this.translateY = (this.y + this.translateY) / this.scale;
14542
15288
  }
15289
+ /**
15290
+ * Updates width, height, x, y based on current points and strokeWidth.
15291
+ * Does NOT modify translateX/translateY (use updateDimensions for initial setup).
15292
+ */
15293
+ updateBoundingBox() {
15294
+ const rotatedPoints = this.points.map(([x, y]) => {
15295
+ const rotatedX = x * Math.cos(this.rotation) - y * Math.sin(this.rotation);
15296
+ const rotatedY = x * Math.sin(this.rotation) + y * Math.cos(this.rotation);
15297
+ return [rotatedX, rotatedY];
15298
+ });
15299
+ const minX = Math.min(...rotatedPoints.map(p => p[0] - this.strokeWidth / 2));
15300
+ const minY = Math.min(...rotatedPoints.map(p => p[1] - this.strokeWidth / 2));
15301
+ const maxX = Math.max(...rotatedPoints.map(p => p[0] + this.strokeWidth / 2));
15302
+ const maxY = Math.max(...rotatedPoints.map(p => p[1] + this.strokeWidth / 2));
15303
+ this.width = maxX - minX + this.lineSlack;
15304
+ this.height = maxY - minY + this.lineSlack;
15305
+ this.x = minX;
15306
+ this.y = minY;
15307
+ }
14543
15308
  generateSvgPath() {
14544
15309
  const stroke = this.getStrokeFromPoints(this.points, this.strokeWidth);
14545
15310
  return this.getSvgPathFromStroke(stroke);
@@ -14780,7 +15545,7 @@ class KritzelLine extends KritzelBaseObject {
14780
15545
  this.translateY = config?.translateY ?? 0;
14781
15546
  this.scale = config?.scale ?? 1;
14782
15547
  this.strokeWidth = config?.strokeWidth ?? 4;
14783
- this.stroke = config?.stroke ?? '#000000';
15548
+ this.stroke = config?.stroke ?? { light: '#000000', dark: '#ffffff' };
14784
15549
  this.startAnchor = config?.startAnchor;
14785
15550
  this.endAnchor = config?.endAnchor;
14786
15551
  this.arrows = config?.arrows;
@@ -14802,7 +15567,7 @@ class KritzelLine extends KritzelBaseObject {
14802
15567
  object.translateY = options?.translateY ?? 0;
14803
15568
  object.scale = options?.scale ?? 1;
14804
15569
  object.strokeWidth = options?.strokeWidth ?? 4;
14805
- object.stroke = options?.stroke ?? '#000000';
15570
+ object.stroke = options?.stroke ?? { light: '#000000', dark: '#ffffff' };
14806
15571
  object.opacity = options?.opacity ?? 1;
14807
15572
  object.startAnchor = options?.startAnchor;
14808
15573
  object.endAnchor = options?.endAnchor;
@@ -15315,7 +16080,8 @@ class KritzelLine extends KritzelBaseObject {
15315
16080
  /** Get the arrow fill color for start or end, defaulting to stroke color */
15316
16081
  getArrowFill(end) {
15317
16082
  const config = end === 'start' ? this.arrows?.start : this.arrows?.end;
15318
- return config?.fill ?? this.stroke;
16083
+ const color = config?.fill ?? this.stroke;
16084
+ return KritzelColorHelper.resolveThemeColor(color);
15319
16085
  }
15320
16086
  /**
15321
16087
  * Generate SVG path data for an arrow head based on the given style.
@@ -15842,39 +16608,8 @@ class KritzelBaseTool {
15842
16608
  }
15843
16609
  }
15844
16610
 
15845
- /**
15846
- * Default color palette shared across all tool configurations.
15847
- * This ensures consistency in color options throughout the application.
15848
- */
15849
- const DEFAULT_COLOR_PALETTE = [
15850
- '#000000',
15851
- '#ff5252',
15852
- '#ffbc00',
15853
- '#00c853',
15854
- '#0000FF',
15855
- '#d500f9',
15856
- '#fafafa',
15857
- '#a52714',
15858
- '#ee8100',
15859
- '#558b2f',
15860
- '#01579b',
15861
- '#8e24aa',
15862
- '#90a4ae',
15863
- '#ff4081',
15864
- '#ff6e40',
15865
- '#aeea00',
15866
- '#304ffe',
15867
- '#7c4dff',
15868
- '#cfd8dc',
15869
- '#f8bbd0',
15870
- '#ffccbc',
15871
- '#f0f4c3',
15872
- '#9fa8da',
15873
- '#d1c4e9',
15874
- ];
15875
-
15876
16611
  class KritzelBrushTool extends KritzelBaseTool {
15877
- color = '#000000';
16612
+ color = DEFAULT_COLOR_PALETTE[0];
15878
16613
  size = 6;
15879
16614
  opacity = 1;
15880
16615
  palette = [...DEFAULT_COLOR_PALETTE];
@@ -16363,35 +17098,10 @@ class KritzelSelectionGroup extends KritzelBaseObject {
16363
17098
  }
16364
17099
 
16365
17100
  class KritzelLineTool extends KritzelBaseTool {
16366
- color = '#000000';
17101
+ color = DEFAULT_COLOR_PALETTE[0];
16367
17102
  size = 4;
16368
17103
  opacity = 1;
16369
- palette = [
16370
- '#000000',
16371
- '#ff5252',
16372
- '#ffbc00',
16373
- '#00c853',
16374
- '#0000FF',
16375
- '#d500f9',
16376
- '#fafafa',
16377
- '#a52714',
16378
- '#ee8100',
16379
- '#558b2f',
16380
- '#01579b',
16381
- '#8e24aa',
16382
- '#90a4ae',
16383
- '#ff4081',
16384
- '#ff6e40',
16385
- '#aeea00',
16386
- '#304ffe',
16387
- '#7c4dff',
16388
- '#cfd8dc',
16389
- '#f8bbd0',
16390
- '#ffccbc',
16391
- '#f0f4c3',
16392
- '#9fa8da',
16393
- '#d1c4e9',
16394
- ];
17104
+ palette = [...DEFAULT_COLOR_PALETTE];
16395
17105
  /** Arrow head configuration for lines created with this tool */
16396
17106
  arrows;
16397
17107
  _startX = 0;
@@ -16745,25 +17455,9 @@ class KritzelImageTool extends KritzelBaseTool {
16745
17455
  class KritzelTextTool extends KritzelBaseTool {
16746
17456
  fontFamily = 'Arial';
16747
17457
  fontSize = 16;
16748
- fontColor = '#000000';
17458
+ fontColor = DEFAULT_COLOR_PALETTE[0];
16749
17459
  opacity = 1;
16750
- palette = [
16751
- '#000000',
16752
- '#FFFFFF',
16753
- '#FF0000',
16754
- '#00FF00',
16755
- '#0000FF',
16756
- '#FFFF00',
16757
- '#FF00FF',
16758
- '#00FFFF',
16759
- '#808080',
16760
- '#C0C0C0',
16761
- '#800000',
16762
- '#008000',
16763
- '#000080',
16764
- '#808000',
16765
- '#800080',
16766
- ];
17460
+ palette = [...DEFAULT_COLOR_PALETTE];
16767
17461
  constructor(core) {
16768
17462
  super(core);
16769
17463
  }
@@ -16797,12 +17491,11 @@ class KritzelTextTool extends KritzelBaseTool {
16797
17491
  const clientY = event.clientY - this._core.store.offsetY;
16798
17492
  const viewportScale = this._core.store.state.scale;
16799
17493
  const lockScale = this._core.store.state.lockDrawingScale;
16800
- const divider = lockScale ? viewportScale : 1;
16801
17494
  const text = KritzelText.create(this._core, this.fontSize, this.fontFamily, lockScale ? 1 : viewportScale);
16802
17495
  text.fontColor = this.fontColor;
16803
17496
  text.opacity = this.opacity;
16804
- text.translateX = (clientX - this._core.store.state.translateX) / divider;
16805
- text.translateY = (clientY - this._core.store.state.translateY) / divider;
17497
+ text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
17498
+ text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
16806
17499
  text.zIndex = this._core.store.currentZIndex;
16807
17500
  this._core.store.state.objects.insert(text);
16808
17501
  this._core.rerender();
@@ -16835,12 +17528,11 @@ class KritzelTextTool extends KritzelBaseTool {
16835
17528
  const clientY = Math.round(activePointers[0].clientY - this._core.store.offsetY);
16836
17529
  const viewportScale = this._core.store.state.scale;
16837
17530
  const lockScale = this._core.store.state.lockDrawingScale;
16838
- const divider = lockScale ? viewportScale : 1;
16839
17531
  const text = KritzelText.create(this._core, this.fontSize, this.fontFamily, lockScale ? 1 : viewportScale);
16840
17532
  text.fontColor = this.fontColor;
16841
17533
  text.opacity = this.opacity;
16842
- text.translateX = (clientX - this._core.store.state.translateX) / divider;
16843
- text.translateY = (clientY - this._core.store.state.translateY) / divider;
17534
+ text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
17535
+ text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
16844
17536
  text.zIndex = this._core.store.currentZIndex;
16845
17537
  this._core.store.state.objects.insert(text);
16846
17538
  this._core.rerender();
@@ -16891,7 +17583,7 @@ KritzelIconRegistry.registerIcons({
16891
17583
  '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>',
16892
17584
  '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>',
16893
17585
  '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>',
16894
- '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>',
17586
+ '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>',
16895
17587
  '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>',
16896
17588
  '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>',
16897
17589
  '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>',
@@ -17541,8 +18233,8 @@ class KritzelSelectionBox extends KritzelBaseObject {
17541
18233
  object.workspaceId = core.store.state.activeWorkspace.id;
17542
18234
  object.scale = core.store.state.scale;
17543
18235
  object.zIndex = 99999;
17544
- object.backgroundColor = 'var(--kritzel-selection-box-background-color, rgba(0, 122, 255, 0.2))';
17545
- object.borderColor = 'var(--kritzel-selection-box-border-color, rgba(0, 122, 255, 0.5))';
18236
+ object.backgroundColor = { light: 'rgba(0, 122, 255, 0.2)', dark: 'rgba(0, 122, 255, 0.2)' };
18237
+ object.borderColor = { light: 'rgba(0, 122, 255, 0.5)', dark: 'rgba(0, 122, 255, 0.5)' };
17546
18238
  object.borderWidth = 2;
17547
18239
  object.height = 0;
17548
18240
  object.width = 0;
@@ -17970,7 +18662,7 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
17970
18662
  t,
17971
18663
  edgeX,
17972
18664
  edgeY,
17973
- lineStroke: line.stroke,
18665
+ lineStroke: KritzelColorHelper.resolveThemeColor(line.stroke),
17974
18666
  lineStrokeWidth: line.strokeWidth / line.scale,
17975
18667
  arrowOffset: line.hasStartArrow ? line.getArrowSize('start') / line.scale : undefined,
17976
18668
  arrowStyle: line.hasStartArrow ? line.arrows?.start?.style : undefined,
@@ -18032,7 +18724,7 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
18032
18724
  t,
18033
18725
  edgeX,
18034
18726
  edgeY,
18035
- lineStroke: line.stroke,
18727
+ lineStroke: KritzelColorHelper.resolveThemeColor(line.stroke),
18036
18728
  lineStrokeWidth: line.strokeWidth / line.scale,
18037
18729
  arrowOffset: line.hasEndArrow ? line.getArrowSize('end') / line.scale : undefined,
18038
18730
  arrowStyle: line.hasEndArrow ? line.arrows?.end?.style : undefined,
@@ -18215,12 +18907,12 @@ exports.ShapeType = void 0;
18215
18907
  class KritzelShape extends KritzelBaseObject {
18216
18908
  __class__ = 'KritzelShape';
18217
18909
  shapeType = exports.ShapeType.Rectangle;
18218
- fillColor = 'transparent';
18219
- strokeColor = '#000000';
18910
+ fillColor = { light: 'transparent', dark: 'transparent' };
18911
+ strokeColor = { light: '#000000', dark: '#ffffff' };
18220
18912
  strokeWidth = 4;
18221
18913
  fontFamily = 'Arial';
18222
18914
  fontSize = 16;
18223
- fontColor = '#000000';
18915
+ fontColor = { light: '#000000', dark: '#ffffff' };
18224
18916
  /** Screen-space x coordinate of the shape's top-left corner (like Path.x) */
18225
18917
  x = 0;
18226
18918
  /** Screen-space y coordinate of the shape's top-left corner (like Path.y) */
@@ -18254,12 +18946,12 @@ class KritzelShape extends KritzelBaseObject {
18254
18946
  this.width = config.width ?? 100;
18255
18947
  this.height = config.height ?? 100;
18256
18948
  this.shapeType = config.shapeType ?? exports.ShapeType.Rectangle;
18257
- this.fillColor = config.fillColor ?? 'transparent';
18258
- this.strokeColor = config.strokeColor ?? '#000000';
18949
+ this.fillColor = config.fillColor ?? { light: 'transparent', dark: 'transparent' };
18950
+ this.strokeColor = config.strokeColor ?? { light: '#000000', dark: '#ffffff' };
18259
18951
  this.strokeWidth = config.strokeWidth ?? 4;
18260
18952
  this.fontSize = config.fontSize ?? 16;
18261
18953
  this.fontFamily = config.fontFamily ?? 'Arial';
18262
- this.fontColor = config.fontColor ?? '#000000';
18954
+ this.fontColor = config.fontColor ?? { light: '#000000', dark: '#ffffff' };
18263
18955
  this.scale = config.scale ?? 1;
18264
18956
  this.scaleFactor = config.scaleX ?? 1;
18265
18957
  }
@@ -18284,14 +18976,14 @@ class KritzelShape extends KritzelBaseObject {
18284
18976
  object.width = config?.width ?? 100;
18285
18977
  object.height = config?.height ?? 100;
18286
18978
  object.shapeType = config?.shapeType ?? exports.ShapeType.Rectangle;
18287
- object.fillColor = config?.fillColor ?? 'transparent';
18288
- object.strokeColor = config?.strokeColor ?? '#000000';
18979
+ object.fillColor = config?.fillColor ?? { light: 'transparent', dark: 'transparent' };
18980
+ object.strokeColor = config?.strokeColor ?? { light: '#000000', dark: '#ffffff' };
18289
18981
  object.strokeWidth = config?.strokeWidth ?? 4;
18290
18982
  object.opacity = config?.opacity ?? 1;
18291
18983
  object.fontSize = config?.fontSize ?? 16;
18292
18984
  object.fontFamily = config?.fontFamily ?? 'Arial';
18293
- object.fontColor = config?.fontColor ?? '#000000';
18294
- object.backgroundColor = 'transparent';
18985
+ object.fontColor = config?.fontColor ?? { light: '#000000', dark: '#ffffff' };
18986
+ object.backgroundColor = { light: 'transparent', dark: 'transparent' };
18295
18987
  object.scaleFactor = 1;
18296
18988
  object.scale = config?.scale ?? core.store.state.scale;
18297
18989
  object.zIndex = core.store.currentZIndex;
@@ -18333,7 +19025,7 @@ class KritzelShape extends KritzelBaseObject {
18333
19025
  }
18334
19026
  element.style.fontFamily = this.fontFamily;
18335
19027
  element.style.fontSize = `${this.fontSize}pt`;
18336
- element.style.color = this.fontColor;
19028
+ element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
18337
19029
  element.style.whiteSpace = 'pre-wrap';
18338
19030
  element.style.wordWrap = 'break-word';
18339
19031
  element.innerHTML = '';
@@ -18603,7 +19295,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
18603
19295
  get color() {
18604
19296
  const objects = this.flattenObjects(this.getSelectedObjects());
18605
19297
  if (objects.length === 0)
18606
- return '#000000';
19298
+ return DEFAULT_COLOR_PALETTE[0];
18607
19299
  for (const obj of objects) {
18608
19300
  if (obj instanceof KritzelPath)
18609
19301
  return obj.fill;
@@ -18614,7 +19306,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
18614
19306
  if (obj instanceof KritzelShape)
18615
19307
  return obj.strokeColor;
18616
19308
  }
18617
- return '#000000';
19309
+ return DEFAULT_COLOR_PALETTE[0];
18618
19310
  }
18619
19311
  set color(value) {
18620
19312
  const objects = this.flattenObjects(this.getSelectedObjects());
@@ -18678,7 +19370,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
18678
19370
  if (obj instanceof KritzelShape)
18679
19371
  return obj.fillColor;
18680
19372
  }
18681
- return 'transparent';
19373
+ return { light: 'transparent', dark: 'transparent' };
18682
19374
  }
18683
19375
  set fillColor(value) {
18684
19376
  const objects = this.flattenObjects(this.getSelectedObjects());
@@ -18686,7 +19378,9 @@ class KritzelSelectionTool extends KritzelBaseTool {
18686
19378
  if (obj instanceof KritzelShape) {
18687
19379
  this._core.updateObject(obj, { fillColor: value });
18688
19380
  // When switching to fill mode, also update stroke color to match
18689
- if (value !== 'transparent') {
19381
+ const isTransparent = typeof value === 'string' ? value === 'transparent' :
19382
+ (value.light === 'transparent' && value.dark === 'transparent');
19383
+ if (!isTransparent) {
18690
19384
  this._core.updateObject(obj, { strokeColor: value });
18691
19385
  }
18692
19386
  }
@@ -36372,7 +37066,7 @@ class KritzelAnchorManager {
36372
37066
 
36373
37067
  const DEFAULT_BRUSH_CONFIG = {
36374
37068
  type: 'pen',
36375
- color: '#000000',
37069
+ color: DEFAULT_COLOR_PALETTE[0],
36376
37070
  size: 16,
36377
37071
  palettes: {
36378
37072
  pen: [...DEFAULT_COLOR_PALETTE],
@@ -36380,14 +37074,14 @@ const DEFAULT_BRUSH_CONFIG = {
36380
37074
  };
36381
37075
 
36382
37076
  const DEFAULT_TEXT_CONFIG = {
36383
- color: '#000000',
37077
+ color: DEFAULT_COLOR_PALETTE[0],
36384
37078
  size: 8,
36385
37079
  fontFamily: 'Arial',
36386
37080
  palette: [...DEFAULT_COLOR_PALETTE],
36387
37081
  };
36388
37082
 
36389
37083
  const DEFAULT_LINE_TOOL_CONFIG = {
36390
- color: '#000000',
37084
+ color: DEFAULT_COLOR_PALETTE[0],
36391
37085
  size: 4,
36392
37086
  palette: [...DEFAULT_COLOR_PALETTE],
36393
37087
  arrows: {
@@ -36411,6 +37105,7 @@ exports.KritzelBaseObject = KritzelBaseObject;
36411
37105
  exports.KritzelBaseTool = KritzelBaseTool;
36412
37106
  exports.KritzelBrushTool = KritzelBrushTool;
36413
37107
  exports.KritzelClassHelper = KritzelClassHelper;
37108
+ exports.KritzelColorHelper = KritzelColorHelper;
36414
37109
  exports.KritzelCursorHelper = KritzelCursorHelper;
36415
37110
  exports.KritzelDevicesHelper = KritzelDevicesHelper;
36416
37111
  exports.KritzelEraserTool = KritzelEraserTool;
@@ -36429,6 +37124,7 @@ exports.KritzelSelectionTool = KritzelSelectionTool;
36429
37124
  exports.KritzelShape = KritzelShape;
36430
37125
  exports.KritzelText = KritzelText;
36431
37126
  exports.KritzelTextTool = KritzelTextTool;
37127
+ exports.KritzelThemeManager = KritzelThemeManager;
36432
37128
  exports.KritzelToolRegistry = KritzelToolRegistry;
36433
37129
  exports.KritzelWorkspace = KritzelWorkspace;
36434
37130
  exports.ObjectHelper = ObjectHelper;
@@ -36440,6 +37136,7 @@ exports.create = create$8;
36440
37136
  exports.createDecoder = createDecoder$1;
36441
37137
  exports.createEncoder = createEncoder$1;
36442
37138
  exports.createUint8ArrayFromArrayBuffer = createUint8ArrayFromArrayBuffer;
37139
+ exports.darkTheme = darkTheme;
36443
37140
  exports.encodeStateAsUpdate = encodeStateAsUpdate;
36444
37141
  exports.encodeStateVector = encodeStateVector;
36445
37142
  exports.equalityDeep = equalityDeep$1;
@@ -36448,6 +37145,7 @@ exports.fromBase64 = fromBase64;
36448
37145
  exports.getUnixTime = getUnixTime$1;
36449
37146
  exports.isNode = isNode;
36450
37147
  exports.length = length$2;
37148
+ exports.lightTheme = lightTheme;
36451
37149
  exports.map = map;
36452
37150
  exports.min = min$2;
36453
37151
  exports.offChange = offChange;