react-klinecharts-ui 1.1.0 → 1.2.0

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.
package/README.md CHANGED
@@ -750,6 +750,7 @@ const {
750
750
  isLocked,
751
751
  isVisible,
752
752
  autoRetrigger,
753
+ overlays,
753
754
  selectTool,
754
755
  clearActiveTool,
755
756
  setMagnetMode,
@@ -757,24 +758,31 @@ const {
757
758
  toggleVisibility,
758
759
  removeAllDrawings,
759
760
  setAutoRetrigger,
761
+ removeDrawing,
762
+ setDrawingVisible,
763
+ setDrawingLocked,
760
764
  } = useDrawingTools();
761
765
  ```
762
766
 
763
- | Field/Method | Type | Description |
764
- | --------------------- | -------------------------------- | ------------------------------------------------------- |
765
- | `categories` | `DrawingCategoryItem[]` | Tool categories with nested tools |
766
- | `activeTool` | `string \| null` | Name of the last selected tool |
767
- | `magnetMode` | `"normal" \| "weak" \| "strong"` | Snap-to-OHLC mode |
768
- | `isLocked` | `boolean` | Whether all drawings are locked |
769
- | `isVisible` | `boolean` | Whether all drawings are visible |
770
- | `autoRetrigger` | `boolean` | Re-arm the tool after finishing a shape (default `true`) |
771
- | `selectTool(name)` | | Start drawing via `chart.createOverlay` |
772
- | `clearActiveTool()` | — | Deselect tool (local state only) |
773
- | `setMagnetMode(mode)` | — | Change magnet mode for all existing and future drawings |
774
- | `toggleLock()` | — | Toggle lock on all drawings |
775
- | `toggleVisibility()` | — | Show/hide all drawings |
776
- | `removeAllDrawings()` | — | Remove all drawings in the `drawing_tools` group |
777
- | `setAutoRetrigger(enabled)` | — | Enable/disable auto re-arming |
767
+ | Field/Method | Type | Description |
768
+ | ------------------------ | -------------------------------- | ------------------------------------------------------- |
769
+ | `categories` | `DrawingCategoryItem[]` | Tool categories with nested tools |
770
+ | `activeTool` | `string \| null` | Name of the last selected tool |
771
+ | `magnetMode` | `"normal" \| "weak" \| "strong"` | Snap-to-OHLC mode |
772
+ | `isLocked` | `boolean` | Whether all drawings are locked |
773
+ | `isVisible` | `boolean` | Whether all drawings are visible |
774
+ | `autoRetrigger` | `boolean` | Re-arm the tool after finishing a shape (default `true`) |
775
+ | `overlays` | `DrawingOverlayInfo[]` | Reactive list of drawings in the `drawing_tools` group |
776
+ | `selectTool(name)` | — | Start drawing via `chart.createOverlay` |
777
+ | `clearActiveTool()` | — | Deselect tool (local state only) |
778
+ | `setMagnetMode(mode)` | — | Change magnet mode for all existing and future drawings |
779
+ | `toggleLock()` | — | Toggle lock on all drawings |
780
+ | `toggleVisibility()` | — | Show/hide all drawings |
781
+ | `removeAllDrawings()` | — | Remove all drawings in the `drawing_tools` group |
782
+ | `setAutoRetrigger(enabled)` | — | Enable/disable auto re-arming |
783
+ | `removeDrawing(id)` | — | Remove a single drawing by id |
784
+ | `setDrawingVisible(id, visible)` | — | Show/hide a single drawing |
785
+ | `setDrawingLocked(id, locked)` | — | Lock/unlock a single drawing |
778
786
 
779
787
  ```typescript
780
788
  interface DrawingToolItem {
@@ -786,8 +794,39 @@ interface DrawingCategoryItem {
786
794
  key: string; // "singleLine" | "moreLine" | "polygon" | "fibonacci" | "wave"
787
795
  tools: DrawingToolItem[];
788
796
  }
797
+
798
+ interface DrawingOverlayInfo {
799
+ id: string; // Stable id from klinecharts (chart.getOverlays()[].id)
800
+ name: string; // Overlay name, e.g. "segment", "fibonacciLine", "arrow"
801
+ paneId: string; // Pane id where the drawing lives
802
+ locked: boolean; // Current lock state
803
+ visible: boolean; // Current visibility
804
+ }
789
805
  ```
790
806
 
807
+ #### Per-drawing management
808
+
809
+ `overlays` is a **reactive** snapshot of the drawings in the `drawing_tools` group. It updates when a drawing is created (via `selectTool` + finishing a shape on the canvas), removed, or has its `locked`/`visible` properties changed — both through the per-drawing operations above and through the batch operations (`toggleLock`, `toggleVisibility`, `removeAllDrawings`).
810
+
811
+ Because klinecharts v10 has no overlay change events, the hook also runs a 1s polling fallback so changes made **outside** the hook (e.g. the user pressing <kbd>Delete</kbd> via klinecharts, or undo/redo) are still reflected.
812
+
813
+ ```typescript
814
+ // Build an Object Tree panel from `overlays`
815
+ const { overlays, removeDrawing, setDrawingVisible, setDrawingLocked } = useDrawingTools();
816
+ // overlays.map((o) => (
817
+ // <Row
818
+ // key={o.id}
819
+ // label={drawingLabel(o.name)} // "segment" -> "segment" locale key
820
+ // visible={o.visible}
821
+ // locked={o.locked}
822
+ // onToggleVis={() => setDrawingVisible(o.id, !o.visible)}
823
+ // onDel={() => removeDrawing(o.id)}
824
+ // />
825
+ // ));
826
+ ```
827
+
828
+ `drawingLabel(name)` is an exported helper that maps a klinecharts overlay name to its `localeKey` using `DRAWING_CATEGORIES` (falls back to the name itself when the tool is unknown), so consumers don't have to duplicate the category table.
829
+
791
830
  **Categories and tools:**
792
831
 
793
832
  | Category (`key`) | Tools |
package/dist/index.cjs CHANGED
@@ -1358,6 +1358,25 @@ var DRAWING_CATEGORIES = [
1358
1358
 
1359
1359
  // src/hooks/useDrawingTools.ts
1360
1360
  var DRAWING_GROUP_ID = "drawing_tools";
1361
+ var DRAWING_NAME_TO_LOCALE_KEY = new Map(
1362
+ DRAWING_CATEGORIES.flatMap(
1363
+ (cat) => cat.tools.map((tool) => [tool.name, tool.localeKey])
1364
+ )
1365
+ );
1366
+ function drawingLabel(name) {
1367
+ return DRAWING_NAME_TO_LOCALE_KEY.get(name) ?? name;
1368
+ }
1369
+ function overlaysEqual(a, b) {
1370
+ if (a.length !== b.length) return false;
1371
+ for (let i = 0; i < a.length; i++) {
1372
+ const x = a[i];
1373
+ const y = b[i];
1374
+ if (x.id !== y.id || x.name !== y.name || x.paneId !== y.paneId || x.locked !== y.locked || x.visible !== y.visible) {
1375
+ return false;
1376
+ }
1377
+ }
1378
+ return true;
1379
+ }
1361
1380
  function useDrawingTools() {
1362
1381
  const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
1363
1382
  const { undoRedoListenerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
@@ -1378,6 +1397,34 @@ function useDrawingTools() {
1378
1397
  isVisibleRef.current = isVisible;
1379
1398
  magnetModeRef.current = magnetMode;
1380
1399
  });
1400
+ const [overlays2, setOverlays] = react.useState([]);
1401
+ const refreshOverlays = react.useCallback(() => {
1402
+ if (!state.chart) {
1403
+ setOverlays((prev) => prev.length === 0 ? prev : []);
1404
+ return;
1405
+ }
1406
+ const list = state.chart.getOverlays({ groupId: DRAWING_GROUP_ID });
1407
+ const next = list.map((o) => ({
1408
+ id: o.id,
1409
+ name: o.name,
1410
+ paneId: o.paneId,
1411
+ locked: !!o.lock,
1412
+ visible: o.visible !== false
1413
+ // klinecharts default = true
1414
+ }));
1415
+ setOverlays((prev) => overlaysEqual(prev, next) ? prev : next);
1416
+ }, [state.chart]);
1417
+ const refreshOverlaysRef = react.useRef(() => {
1418
+ });
1419
+ react.useEffect(() => {
1420
+ refreshOverlaysRef.current = refreshOverlays;
1421
+ });
1422
+ react.useEffect(() => {
1423
+ if (!state.chart) return;
1424
+ queueMicrotask(() => refreshOverlaysRef.current());
1425
+ const interval = setInterval(() => refreshOverlaysRef.current(), 1e3);
1426
+ return () => clearInterval(interval);
1427
+ }, [state.chart, refreshOverlays]);
1381
1428
  const categories = react.useMemo(
1382
1429
  () => DRAWING_CATEGORIES.map((cat) => ({
1383
1430
  key: cat.key,
@@ -1413,6 +1460,7 @@ function useDrawingTools() {
1413
1460
  }
1414
1461
  }
1415
1462
  });
1463
+ refreshOverlaysRef.current();
1416
1464
  if (autoRetriggerRef.current && activeToolRef.current === name) {
1417
1465
  requestAnimationFrame(() => {
1418
1466
  createOverlayForToolRef.current(name);
@@ -1439,49 +1487,52 @@ function useDrawingTools() {
1439
1487
  const setMagnetMode = react.useCallback(
1440
1488
  (mode) => {
1441
1489
  setMagnetModeState(mode);
1442
- const overlays2 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1443
- if (overlays2) {
1490
+ const overlays3 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1491
+ if (overlays3) {
1444
1492
  const overlayMode = mode === "strong" ? "strong_magnet" : mode === "weak" ? "weak_magnet" : "normal";
1445
- overlays2.forEach((overlay) => {
1493
+ overlays3.forEach((overlay) => {
1446
1494
  state.chart?.overrideOverlay({
1447
1495
  id: overlay.id,
1448
1496
  mode: overlayMode
1449
1497
  });
1450
1498
  });
1451
1499
  }
1500
+ refreshOverlaysRef.current();
1452
1501
  },
1453
1502
  [state.chart]
1454
1503
  );
1455
1504
  const toggleLock = react.useCallback(() => {
1456
1505
  const newLocked = !isLocked;
1457
1506
  setIsLocked(newLocked);
1458
- const overlays2 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1459
- if (overlays2) {
1460
- overlays2.forEach((overlay) => {
1507
+ const overlays3 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1508
+ if (overlays3) {
1509
+ overlays3.forEach((overlay) => {
1461
1510
  state.chart?.overrideOverlay({
1462
1511
  id: overlay.id,
1463
1512
  lock: newLocked
1464
1513
  });
1465
1514
  });
1466
1515
  }
1516
+ refreshOverlaysRef.current();
1467
1517
  }, [state.chart, isLocked]);
1468
1518
  const toggleVisibility = react.useCallback(() => {
1469
1519
  const newVisible = !isVisible;
1470
1520
  setIsVisible(newVisible);
1471
- const overlays2 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1472
- if (overlays2) {
1473
- overlays2.forEach((overlay) => {
1521
+ const overlays3 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1522
+ if (overlays3) {
1523
+ overlays3.forEach((overlay) => {
1474
1524
  state.chart?.overrideOverlay({
1475
1525
  id: overlay.id,
1476
1526
  visible: newVisible
1477
1527
  });
1478
1528
  });
1479
1529
  }
1530
+ refreshOverlaysRef.current();
1480
1531
  }, [state.chart, isVisible]);
1481
1532
  const removeAllDrawings = react.useCallback(() => {
1482
- const overlays2 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1483
- if (overlays2 && overlays2.length > 0) {
1484
- const snapshot = overlays2.map((o) => ({
1533
+ const overlays3 = state.chart?.getOverlays({ groupId: DRAWING_GROUP_ID });
1534
+ if (overlays3 && overlays3.length > 0) {
1535
+ const snapshot = overlays3.map((o) => ({
1485
1536
  name: o.name,
1486
1537
  id: o.id,
1487
1538
  points: o.points,
@@ -1495,7 +1546,29 @@ function useDrawingTools() {
1495
1546
  }
1496
1547
  state.chart?.removeOverlay({ groupId: DRAWING_GROUP_ID });
1497
1548
  setActiveTool(null);
1549
+ refreshOverlaysRef.current();
1498
1550
  }, [state.chart, undoRedoListenerRef]);
1551
+ const removeDrawing = react.useCallback(
1552
+ (id) => {
1553
+ state.chart?.removeOverlay({ id, groupId: DRAWING_GROUP_ID });
1554
+ refreshOverlaysRef.current();
1555
+ },
1556
+ [state.chart]
1557
+ );
1558
+ const setDrawingVisible = react.useCallback(
1559
+ (id, visible) => {
1560
+ state.chart?.overrideOverlay({ id, visible });
1561
+ refreshOverlaysRef.current();
1562
+ },
1563
+ [state.chart]
1564
+ );
1565
+ const setDrawingLocked = react.useCallback(
1566
+ (id, locked) => {
1567
+ state.chart?.overrideOverlay({ id, lock: locked });
1568
+ refreshOverlaysRef.current();
1569
+ },
1570
+ [state.chart]
1571
+ );
1499
1572
  return {
1500
1573
  categories,
1501
1574
  activeTool,
@@ -1503,13 +1576,17 @@ function useDrawingTools() {
1503
1576
  isLocked,
1504
1577
  isVisible,
1505
1578
  autoRetrigger,
1579
+ overlays: overlays2,
1506
1580
  selectTool,
1507
1581
  clearActiveTool,
1508
1582
  setMagnetMode,
1509
1583
  toggleLock,
1510
1584
  toggleVisibility,
1511
1585
  removeAllDrawings,
1512
- setAutoRetrigger
1586
+ setAutoRetrigger,
1587
+ removeDrawing,
1588
+ setDrawingVisible,
1589
+ setDrawingLocked
1513
1590
  };
1514
1591
  }
1515
1592
 
@@ -3944,6 +4021,7 @@ exports.TOOLTIP_SHOW_RULES = TOOLTIP_SHOW_RULES;
3944
4021
  exports.WorkspaceProvider = WorkspaceProvider;
3945
4022
  exports.YAXIS_POSITIONS = YAXIS_POSITIONS;
3946
4023
  exports.createDefaultStorage = createDefaultStorage;
4024
+ exports.drawingLabel = drawingLabel;
3947
4025
  exports.resolveStorage = resolveStorage;
3948
4026
  exports.useAlerts = useAlerts;
3949
4027
  exports.useAnnotations = useAnnotations;