@markup-canvas/core 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,6 +11,7 @@ export declare class MarkupCanvas {
11
11
  private rulers;
12
12
  private dragSetup;
13
13
  private keyboardCleanup;
14
+ private textEditModeEnabled;
14
15
  config: Required<MarkupCanvasConfig>;
15
16
  event: EventEmitter<MarkupCanvasEvents>;
16
17
  private _isReady;
@@ -52,6 +53,9 @@ export declare class MarkupCanvas {
52
53
  enableKeyboard(): boolean;
53
54
  disableKeyboard(): boolean;
54
55
  isKeyboardEnabled(): boolean;
56
+ enableTextEditMode(): boolean;
57
+ disableTextEditMode(): boolean;
58
+ isTextEditModeEnabled(): boolean;
55
59
  toggleGrid(): boolean;
56
60
  showGrid(): boolean;
57
61
  hideGrid(): boolean;
@@ -1,3 +1,5 @@
1
1
  import type { MarkupCanvas } from "@/lib/MarkupCanvas.js";
2
2
  import type { MarkupCanvasConfig } from "@/types/index.js";
3
- export declare function setupKeyboardEvents(canvas: MarkupCanvas, config: Required<MarkupCanvasConfig>): () => void;
3
+ export declare function setupKeyboardEvents(canvas: MarkupCanvas, config: Required<MarkupCanvasConfig>, options?: {
4
+ textEditModeEnabled?: boolean;
5
+ }): () => void;
@@ -0,0 +1,3 @@
1
+ import type { MarkupCanvas } from "@/lib/MarkupCanvas.js";
2
+ import type { PostMessageAction } from "@/types/events";
3
+ export declare function processPostMessage(canvas: MarkupCanvas, action: PostMessageAction, payload: string | number | boolean | object, canvasName: string): void;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Markup Canvas
3
3
  * High-performance markup canvas with zoom and pan capabilities
4
- * @version 1.3.2
4
+ * @version 1.3.4
5
5
  */
6
6
  'use strict';
7
7
 
@@ -22,7 +22,7 @@ const EDITOR_PRESET = {
22
22
  enableKeyboard: true,
23
23
  bindKeyboardEventsTo: "document",
24
24
  // Zoom behavior
25
- zoomSpeed: 1.5,
25
+ zoomSpeed: 4,
26
26
  minZoom: 0.05,
27
27
  maxZoom: 80,
28
28
  enableTransition: false,
@@ -54,7 +54,7 @@ const EDITOR_PRESET = {
54
54
  canvasBackgroundColorDark: "transparent",
55
55
  // Ruler styling
56
56
  rulerBackgroundColor: "oklch(100% 0 0 / 0.96)",
57
- rulerBorderColor: "oklch(96.7% 0.001 286.375)",
57
+ rulerBorderColor: "oklch(0.322 0.0095 285.919)",
58
58
  rulerTextColor: "oklch(70.5% 0.015 286.067)",
59
59
  rulerTickColor: "oklch(92% 0.004 286.32)",
60
60
  gridColor: "rgba(232, 86, 193, 0.5)",
@@ -948,7 +948,8 @@ function getAdaptiveZoomSpeed(canvas, baseSpeed) {
948
948
  }
949
949
  }
950
950
 
951
- function setupKeyboardEvents(canvas, config) {
951
+ function setupKeyboardEvents(canvas, config, options) {
952
+ const textEditModeEnabled = options?.textEditModeEnabled ?? false;
952
953
  function handleKeyDown(event) {
953
954
  if (!(event instanceof KeyboardEvent))
954
955
  return;
@@ -958,23 +959,38 @@ function setupKeyboardEvents(canvas, config) {
958
959
  const newTransform = {};
959
960
  switch (event.key) {
960
961
  case "ArrowLeft":
962
+ if (textEditModeEnabled) {
963
+ return;
964
+ }
961
965
  newTransform.translateX = canvas.transform.translateX + config.keyboardPanStep;
962
966
  handled = true;
963
967
  break;
964
968
  case "ArrowRight":
969
+ if (textEditModeEnabled) {
970
+ return;
971
+ }
965
972
  newTransform.translateX = canvas.transform.translateX - config.keyboardPanStep;
966
973
  handled = true;
967
974
  break;
968
975
  case "ArrowUp":
976
+ if (textEditModeEnabled) {
977
+ return;
978
+ }
969
979
  newTransform.translateY = canvas.transform.translateY + config.keyboardPanStep;
970
980
  handled = true;
971
981
  break;
972
982
  case "ArrowDown":
983
+ if (textEditModeEnabled) {
984
+ return;
985
+ }
973
986
  newTransform.translateY = canvas.transform.translateY - config.keyboardPanStep;
974
987
  handled = true;
975
988
  break;
976
989
  case "=":
977
990
  case "+":
991
+ if (textEditModeEnabled) {
992
+ return;
993
+ }
978
994
  {
979
995
  const adaptiveZoomStep = config.enableAdaptiveSpeed
980
996
  ? getAdaptiveZoomSpeed(canvas, config.keyboardZoomStep)
@@ -984,6 +1000,9 @@ function setupKeyboardEvents(canvas, config) {
984
1000
  }
985
1001
  break;
986
1002
  case "-":
1003
+ if (textEditModeEnabled) {
1004
+ return;
1005
+ }
987
1006
  {
988
1007
  const adaptiveZoomStep = config.enableAdaptiveSpeed
989
1008
  ? getAdaptiveZoomSpeed(canvas, config.keyboardZoomStep)
@@ -1330,117 +1349,125 @@ function sendPostMessageError(canvasName, action, error) {
1330
1349
  }, "*");
1331
1350
  }
1332
1351
 
1333
- function setupPostMessageEvents(canvas) {
1334
- const handleMessage = (event) => {
1335
- const data = event.data;
1336
- if (!["markup-canvas", "application"].includes(data.source)) {
1337
- return;
1338
- }
1339
- console.log("data", event.data);
1340
- const canvasName = canvas.config.name || "markupCanvas";
1341
- if (data.canvasName !== canvasName) {
1342
- console.log("canvasName", data.canvasName, "!==", canvasName);
1343
- return;
1344
- }
1345
- const action = data.action;
1346
- const payload = data.data;
1347
- try {
1348
- // View methods
1349
- if (action === "zoomIn") {
1350
- console.log("zoomIn", payload);
1352
+ function processPostMessage(canvas, action, payload, canvasName) {
1353
+ try {
1354
+ // View methods
1355
+ switch (action) {
1356
+ case "zoomIn":
1351
1357
  canvas.zoomIn(payload);
1352
- }
1353
- else if (action === "zoomOut") {
1358
+ break;
1359
+ case "zoomOut":
1354
1360
  canvas.zoomOut(payload);
1355
- }
1356
- else if (action === "setZoom") {
1361
+ break;
1362
+ case "setZoom": {
1357
1363
  const zoomLevel = payload;
1358
1364
  if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
1359
1365
  throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
1360
1366
  }
1361
1367
  canvas.setZoom(zoomLevel);
1368
+ break;
1362
1369
  }
1363
- else if (action === "resetZoom") {
1370
+ case "resetZoom":
1364
1371
  canvas.resetZoom();
1365
- }
1366
- else if (action === "panLeft") {
1372
+ break;
1373
+ case "panLeft":
1367
1374
  canvas.panLeft(payload);
1368
- }
1369
- else if (action === "panRight") {
1375
+ break;
1376
+ case "panRight":
1370
1377
  canvas.panRight(payload);
1371
- }
1372
- else if (action === "panUp") {
1378
+ break;
1379
+ case "panUp":
1373
1380
  canvas.panUp(payload);
1374
- }
1375
- else if (action === "panDown") {
1381
+ break;
1382
+ case "panDown":
1376
1383
  canvas.panDown(payload);
1377
- }
1378
- else if (action === "fitToScreen") {
1384
+ break;
1385
+ case "fitToScreen":
1379
1386
  canvas.fitToScreen();
1380
- }
1381
- else if (action === "centerContent") {
1387
+ break;
1388
+ case "centerContent":
1382
1389
  canvas.centerContent();
1390
+ break;
1391
+ case "panToPoint": {
1392
+ const point = payload;
1393
+ canvas.panToPoint(point.x, point.y);
1394
+ break;
1383
1395
  }
1384
- else if (action === "panToPoint") {
1385
- canvas.panToPoint(payload.x, payload.y);
1386
- }
1387
- else if (action === "resetView") {
1396
+ case "resetView":
1388
1397
  canvas.resetView();
1389
- }
1390
- else if (action === "resetViewToCenter") {
1398
+ break;
1399
+ case "resetViewToCenter":
1391
1400
  canvas.resetViewToCenter();
1392
- }
1401
+ break;
1393
1402
  // Ruler/Grid methods
1394
- else if (action === "toggleRulers") {
1403
+ case "toggleRulers":
1395
1404
  canvas.toggleRulers();
1396
- }
1397
- else if (action === "showRulers") {
1405
+ break;
1406
+ case "showRulers":
1398
1407
  canvas.showRulers();
1399
- }
1400
- else if (action === "hideRulers") {
1408
+ break;
1409
+ case "hideRulers":
1401
1410
  canvas.hideRulers();
1402
- }
1403
- else if (action === "toggleGrid") {
1411
+ break;
1412
+ case "toggleGrid":
1404
1413
  canvas.toggleGrid();
1405
- }
1406
- else if (action === "showGrid") {
1414
+ break;
1415
+ case "showGrid":
1407
1416
  canvas.showGrid();
1408
- }
1409
- else if (action === "hideGrid") {
1417
+ break;
1418
+ case "hideGrid":
1410
1419
  canvas.hideGrid();
1411
- }
1420
+ break;
1412
1421
  // Config methods
1413
- else if (action === "updateThemeMode") {
1422
+ case "updateThemeMode": {
1414
1423
  const mode = payload;
1415
1424
  if (mode !== "light" && mode !== "dark") {
1416
1425
  throw new Error(`Invalid theme mode: ${mode}`);
1417
1426
  }
1418
1427
  canvas.updateThemeMode(mode);
1428
+ break;
1419
1429
  }
1420
- else if (action === "toggleThemeMode") {
1430
+ case "toggleThemeMode": {
1421
1431
  const currentConfig = canvas.getConfig();
1422
1432
  const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
1423
1433
  canvas.updateThemeMode(newMode);
1434
+ break;
1424
1435
  }
1425
1436
  // Transition methods
1426
- else if (action === "updateTransition") {
1437
+ case "updateTransition": {
1427
1438
  const enabled = payload;
1428
1439
  if (typeof enabled !== "boolean") {
1429
1440
  throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
1430
1441
  }
1431
1442
  canvas.updateTransition(enabled);
1443
+ break;
1432
1444
  }
1433
- else if (action === "toggleTransitionMode") {
1445
+ case "toggleTransitionMode":
1434
1446
  canvas.toggleTransitionMode();
1435
- }
1436
- else {
1447
+ break;
1448
+ default:
1437
1449
  throw new Error(`Unknown action: ${action}`);
1438
- }
1439
1450
  }
1440
- catch (error) {
1441
- const errorMessage = error instanceof Error ? error.message : String(error);
1442
- sendPostMessageError(canvasName, action, errorMessage);
1451
+ }
1452
+ catch (error) {
1453
+ const errorMessage = error instanceof Error ? error.message : String(error);
1454
+ sendPostMessageError(canvasName, action, errorMessage);
1455
+ }
1456
+ }
1457
+
1458
+ function setupPostMessageEvents(canvas) {
1459
+ const handleMessage = (event) => {
1460
+ const data = event.data;
1461
+ if (!["markup-canvas", "application"].includes(data.source)) {
1462
+ return;
1443
1463
  }
1464
+ const canvasName = canvas.config.name || "markupCanvas";
1465
+ if (data.canvasName !== canvasName) {
1466
+ return;
1467
+ }
1468
+ const action = data.action;
1469
+ const payload = data.data;
1470
+ processPostMessage(canvas, action, payload, canvasName);
1444
1471
  };
1445
1472
  if (typeof window !== "undefined") {
1446
1473
  window.addEventListener("message", handleMessage);
@@ -1741,7 +1768,6 @@ function createHorizontalRuler(config) {
1741
1768
  height: ${config.rulerSize}px;
1742
1769
  background: var(--ruler-background-color);
1743
1770
  border-bottom: 1px solid var(--ruler-border-color);
1744
- border-right: 1px solid var(--ruler-border-color);
1745
1771
  z-index: ${RULER_Z_INDEX.RULERS};
1746
1772
  pointer-events: none;
1747
1773
  font-family: ${config.rulerFontFamily};
@@ -1763,7 +1789,6 @@ function createVerticalRuler(config) {
1763
1789
  width: ${config.rulerSize}px;
1764
1790
  background: var(--ruler-background-color);
1765
1791
  border-right: 1px solid var(--ruler-border-color);
1766
- border-bottom: 1px solid var(--ruler-border-color);
1767
1792
  z-index: ${RULER_Z_INDEX.RULERS};
1768
1793
  pointer-events: none;
1769
1794
  font-family: ${config.rulerFontFamily};
@@ -2165,6 +2190,9 @@ function bindCanvasToWindow(canvas, config) {
2165
2190
  enable: canvas.enableKeyboard.bind(canvas),
2166
2191
  disable: canvas.disableKeyboard.bind(canvas),
2167
2192
  isEnabled: canvas.isKeyboardEnabled.bind(canvas),
2193
+ enableTextEditMode: canvas.enableTextEditMode.bind(canvas),
2194
+ disableTextEditMode: canvas.disableTextEditMode.bind(canvas),
2195
+ isTextEditModeEnabled: canvas.isTextEditModeEnabled.bind(canvas),
2168
2196
  },
2169
2197
  // Grid group
2170
2198
  grid: {
@@ -2239,6 +2267,7 @@ class MarkupCanvas {
2239
2267
  this.rulers = null;
2240
2268
  this.dragSetup = null;
2241
2269
  this.keyboardCleanup = null;
2270
+ this.textEditModeEnabled = false;
2242
2271
  this.event = new EventEmitter();
2243
2272
  this._isReady = false;
2244
2273
  if (!container) {
@@ -2290,7 +2319,9 @@ class MarkupCanvas {
2290
2319
  }
2291
2320
  // Keyboard events
2292
2321
  withFeatureEnabled(this.config, "enableKeyboard", () => {
2293
- const keyboardCleanup = setupKeyboardEvents(this, this.config);
2322
+ const keyboardCleanup = setupKeyboardEvents(this, this.config, {
2323
+ textEditModeEnabled: this.textEditModeEnabled,
2324
+ });
2294
2325
  this.keyboardCleanup = keyboardCleanup;
2295
2326
  this.cleanupCallbacks.push(keyboardCleanup);
2296
2327
  });
@@ -2404,7 +2435,9 @@ class MarkupCanvas {
2404
2435
  if (this.keyboardCleanup) {
2405
2436
  return true; // Already enabled
2406
2437
  }
2407
- this.keyboardCleanup = setupKeyboardEvents(this, this.config);
2438
+ this.keyboardCleanup = setupKeyboardEvents(this, this.config, {
2439
+ textEditModeEnabled: this.textEditModeEnabled,
2440
+ });
2408
2441
  this.cleanupCallbacks.push(this.keyboardCleanup);
2409
2442
  return true;
2410
2443
  }
@@ -2419,6 +2452,54 @@ class MarkupCanvas {
2419
2452
  isKeyboardEnabled() {
2420
2453
  return this.keyboardCleanup !== null;
2421
2454
  }
2455
+ // Text edit mode control methods
2456
+ enableTextEditMode() {
2457
+ if (this.textEditModeEnabled) {
2458
+ return true; // Already enabled
2459
+ }
2460
+ this.textEditModeEnabled = true;
2461
+ // If keyboard is currently enabled, re-setup with new option
2462
+ if (this.keyboardCleanup) {
2463
+ // Remove old cleanup from callbacks
2464
+ const index = this.cleanupCallbacks.indexOf(this.keyboardCleanup);
2465
+ if (index > -1) {
2466
+ this.cleanupCallbacks.splice(index, 1);
2467
+ }
2468
+ // Cleanup old handler
2469
+ this.keyboardCleanup();
2470
+ // Setup new handler with text edit mode enabled
2471
+ this.keyboardCleanup = setupKeyboardEvents(this, this.config, {
2472
+ textEditModeEnabled: true,
2473
+ });
2474
+ this.cleanupCallbacks.push(this.keyboardCleanup);
2475
+ }
2476
+ return true;
2477
+ }
2478
+ disableTextEditMode() {
2479
+ if (!this.textEditModeEnabled) {
2480
+ return true; // Already disabled
2481
+ }
2482
+ this.textEditModeEnabled = false;
2483
+ // If keyboard is currently enabled, re-setup with new option
2484
+ if (this.keyboardCleanup) {
2485
+ // Remove old cleanup from callbacks
2486
+ const index = this.cleanupCallbacks.indexOf(this.keyboardCleanup);
2487
+ if (index > -1) {
2488
+ this.cleanupCallbacks.splice(index, 1);
2489
+ }
2490
+ // Cleanup old handler
2491
+ this.keyboardCleanup();
2492
+ // Setup new handler with text edit mode disabled
2493
+ this.keyboardCleanup = setupKeyboardEvents(this, this.config, {
2494
+ textEditModeEnabled: false,
2495
+ });
2496
+ this.cleanupCallbacks.push(this.keyboardCleanup);
2497
+ }
2498
+ return true;
2499
+ }
2500
+ isTextEditModeEnabled() {
2501
+ return this.textEditModeEnabled;
2502
+ }
2422
2503
  toggleGrid() {
2423
2504
  const result = toggleGrid(this.rulers);
2424
2505
  if (result) {