react-klinecharts-ui 0.5.0 → 0.6.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
@@ -44,6 +44,8 @@ Many features in this library — including 11 TradingView-style indicators, 9 d
44
44
  - [useAlerts](#usealerts)
45
45
  - [useCrosshair](#usecrosshair)
46
46
  - [useDataExport](#usedataexport)
47
+ - [useHotkeys](#usehotkeys)
48
+ - [useChartAxes](#usechartaxes)
47
49
  6. [Utilities](#utilities)
48
50
  - [createDataLoader](#createdataloader)
49
51
  - [TA (Technical Analysis)](#ta-technical-analysis)
@@ -520,6 +522,10 @@ interface IndicatorInfo {
520
522
  | `getIndicatorParams(name)` | Returns `[{ label, defaultValue }]` or `[]` if no parameters |
521
523
  | `isMainIndicatorActive(name)` | Quick active check |
522
524
  | `isSubIndicatorActive(name)` | Quick active check |
525
+ | `collapseSubIndicator(name)` | Collapse a sub-indicator pane to minimal height (30px) |
526
+ | `expandSubIndicator(name)` | Expand a previously collapsed sub-indicator pane |
527
+ | `isSubIndicatorCollapsed(name)` | Whether the given sub-indicator pane is currently collapsed |
528
+ | `reorderSubIndicator(name, direction)` | Reorder a sub-indicator pane `"up"` or `"down"` |
523
529
  | `getIndicatorAxis(name, isMain)` | Returns the custom `yAxisId` an indicator is bound to, or `undefined` for the default axis |
524
530
  | `bindIndicatorToNewAxis(name, isMain, yAxis?)`| Rebinds an existing indicator to a different Y-axis (omit `yAxis` to return it to the default axis) |
525
531
 
@@ -568,12 +574,14 @@ const {
568
574
  magnetMode,
569
575
  isLocked,
570
576
  isVisible,
577
+ autoRetrigger,
571
578
  selectTool,
572
579
  clearActiveTool,
573
580
  setMagnetMode,
574
581
  toggleLock,
575
582
  toggleVisibility,
576
583
  removeAllDrawings,
584
+ setAutoRetrigger,
577
585
  } = useDrawingTools();
578
586
  ```
579
587
 
@@ -584,12 +592,14 @@ const {
584
592
  | `magnetMode` | `"normal" \| "weak" \| "strong"` | Snap-to-OHLC mode |
585
593
  | `isLocked` | `boolean` | Whether all drawings are locked |
586
594
  | `isVisible` | `boolean` | Whether all drawings are visible |
595
+ | `autoRetrigger` | `boolean` | Re-arm the tool after finishing a shape (default `true`) |
587
596
  | `selectTool(name)` | — | Start drawing via `chart.createOverlay` |
588
597
  | `clearActiveTool()` | — | Deselect tool (local state only) |
589
598
  | `setMagnetMode(mode)` | — | Change magnet mode for all existing and future drawings |
590
599
  | `toggleLock()` | — | Toggle lock on all drawings |
591
600
  | `toggleVisibility()` | — | Show/hide all drawings |
592
601
  | `removeAllDrawings()` | — | Remove all drawings in the `drawing_tools` group |
602
+ | `setAutoRetrigger(enabled)` | — | Enable/disable auto re-arming |
593
603
 
594
604
  ```typescript
595
605
  interface DrawingToolItem {
@@ -612,6 +622,9 @@ interface DrawingCategoryItem {
612
622
  | `polygon` | circle, rect, parallelogram, triangle |
613
623
  | `fibonacci` | fibonacciLine, fibonacciSegment, fibonacciCircle, fibonacciSpiral, fibonacciSpeedResistanceFan, fibonacciExtension, gannBox |
614
624
  | `wave` | xabcd, abcd, threeWaves, fiveWaves, eightWaves, anyWaves |
625
+ | `annotation` | brush |
626
+
627
+ > **Freehand drawing.** The `brush` tool (category `annotation`) uses klinecharts' continuous (freehand) drawing mode — hold and drag to sketch. It is a built-in overlay added in **klinecharts 10.0.0-beta3**, so it requires beta3+ to render.
615
628
 
616
629
  ---
617
630
 
@@ -627,20 +640,25 @@ const settings = useKlinechartsUISettings();
627
640
 
628
641
  | Field | Type | Default | Description |
629
642
  | ------------------------ | --------------- | ---------------- | ------------------------- |
630
- | `candleType` | `string` | `"candle_solid"` | Candle display type |
631
- | `candleUpColor` | `string` | `"#2DC08E"` | Bullish candle color |
632
- | `candleDownColor` | `string` | `"#F92855"` | Bearish candle color |
633
- | `showLastPrice` | `boolean` | `true` | Last price mark on Y-axis |
634
- | `showHighPrice` | `boolean` | `true` | High price mark |
635
- | `showLowPrice` | `boolean` | `true` | Low price mark |
636
- | `showIndicatorLastValue` | `boolean` | `true` | Indicator last value mark |
637
- | `priceAxisType` | `PriceAxisType` | `"normal"` | Y-axis scale type |
638
- | `reverseCoordinate` | `boolean` | `false` | Invert Y-axis |
639
- | `showTimeAxis` | `boolean` | `true` | Show X-axis |
640
- | `showGrid` | `boolean` | `true` | Show grid |
641
- | `showCrosshair` | `boolean` | `true` | Show crosshair |
642
- | `showCandleTooltip` | `boolean` | `true` | OHLCV tooltip |
643
- | `showIndicatorTooltip` | `boolean` | `true` | Indicator tooltip |
643
+ | `candleType` | `string` | `"candle_solid"` | Candle display type |
644
+ | `candleUpColor` | `string` | `"#2DC08E"` | Bullish candle color |
645
+ | `candleDownColor` | `string` | `"#F92855"` | Bearish candle color |
646
+ | `compareRule` | `CompareRule` | `"current_open"` | Baseline rule for compared symbols |
647
+ | `showLastPrice` | `boolean` | `true` | Last price mark on Y-axis |
648
+ | `showLastPriceLine` | `boolean` | `true` | Last price horizontal line |
649
+ | `showHighPrice` | `boolean` | `true` | High price mark |
650
+ | `showLowPrice` | `boolean` | `true` | Low price mark |
651
+ | `showIndicatorLastValue` | `boolean` | `true` | Indicator last value mark |
652
+ | `priceAxisType` | `PriceAxisType` | `"normal"` | Y-axis scale type |
653
+ | `yAxisPosition` | `YAxisPosition` | `"right"` | Y-axis side (`"left" \| "right"`) |
654
+ | `yAxisInside` | `boolean` | `false` | Draw the Y-axis inside the pane |
655
+ | `reverseCoordinate` | `boolean` | `false` | Invert Y-axis |
656
+ | `showTimeAxis` | `boolean` | `true` | Show X-axis |
657
+ | `showGrid` | `boolean` | `true` | Show grid |
658
+ | `showCrosshair` | `boolean` | `true` | Show crosshair |
659
+ | `showCandleTooltip` | `boolean` | `true` | OHLCV tooltip |
660
+ | `showIndicatorTooltip` | `boolean` | `true` | Indicator tooltip |
661
+ | `tooltipShowRule` | `TooltipShowRule`| `"always"` | When to show tooltips |
644
662
 
645
663
  **Candle types:** `candle_solid`, `candle_stroke`, `candle_up_stroke`, `candle_down_stroke`, `ohlc`, `area`
646
664
 
@@ -648,14 +666,17 @@ const settings = useKlinechartsUISettings();
648
666
 
649
667
  #### Extra fields
650
668
 
651
- | Field | Type | Description |
652
- | ---------------- | --------------------------------------------- | ----------------------------------------------------- |
653
- | `candleTypes` | `CandleTypeItem[]` | List of `{ key, localeKey }` for rendering a selector |
654
- | `priceAxisTypes` | `{ key: PriceAxisType; localeKey: string }[]` | List for rendering a selector |
669
+ | Field | Type | Description |
670
+ | ------------------ | ----------------------------------------------- | ----------------------------------------------------- |
671
+ | `candleTypes` | `CandleTypeItem[]` | List of `{ key, localeKey }` for rendering a selector |
672
+ | `priceAxisTypes` | `{ key: PriceAxisType; localeKey: string }[]` | List for rendering a selector |
673
+ | `yAxisPositions` | `{ key: YAxisPosition; localeKey: string }[]` | List for rendering a selector |
674
+ | `compareRules` | `{ key: CompareRule; localeKey: string }[]` | List for rendering a selector |
675
+ | `tooltipShowRules` | `{ key: TooltipShowRule; localeKey: string }[]` | List for rendering a selector |
655
676
 
656
677
  #### Setters
657
678
 
658
- Each field has a corresponding setter: `setCandleType`, `setCandleUpColor`, `setCandleDownColor`, `setShowLastPrice`, `setShowHighPrice`, `setShowLowPrice`, `setShowIndicatorLastValue`, `setPriceAxisType`, `setReverseCoordinate`, `setShowTimeAxis`, `setShowGrid`, `setShowCrosshair`, `setShowCandleTooltip`, `setShowIndicatorTooltip`.
679
+ Each field has a corresponding setter: `setCandleType`, `setCandleUpColor`, `setCandleDownColor`, `setCompareRule`, `setShowLastPrice`, `setShowLastPriceLine`, `setShowHighPrice`, `setShowLowPrice`, `setShowIndicatorLastValue`, `setPriceAxisType`, `setYAxisPosition`, `setYAxisInside`, `setReverseCoordinate`, `setShowTimeAxis`, `setShowGrid`, `setShowCrosshair`, `setShowCandleTooltip`, `setShowIndicatorTooltip`, `setTooltipShowRule`.
659
680
 
660
681
  All setters immediately apply changes via `chart.setStyles(...)`.
661
682
 
@@ -736,7 +757,7 @@ const { containerRef, toggle, isFullscreen } = useFullscreen();
736
757
 
737
758
  Create and manage horizontal price level lines (order lines).
738
759
 
739
- > **Requirement:** The `orderLine` overlay must be registered via `overlays={[orderLine]}` on the provider.
760
+ > **No setup required.** The `orderLine` overlay is registered automatically by `registerExtensions()` (enabled by default). Passing `overlays={[orderLine]}` to the provider still works and is harmless, but is no longer necessary.
740
761
 
741
762
  ```typescript
742
763
  const {
@@ -1021,7 +1042,7 @@ const {
1021
1042
  | Property | Type | Description |
1022
1043
  |----------|------|-------------|
1023
1044
  | `symbols` | `CompareSymbol[]` | Array of comparison symbols with metadata |
1024
- | `addSymbol` | `(ticker: string) => void` | Add a symbol to compare |
1045
+ | `addSymbol` | `(ticker: string, color?: string) => Promise<void>` | Add a symbol to compare (optional line color) |
1025
1046
  | `removeSymbol` | `(ticker: string) => void` | Remove a comparison symbol |
1026
1047
  | `toggleSymbol` | `(ticker: string) => void` | Toggle visibility of a symbol |
1027
1048
  | `clearAll` | `() => void` | Remove all comparison symbols |
@@ -1050,6 +1071,8 @@ const {
1050
1071
  startMeasure,
1051
1072
  cancelMeasure,
1052
1073
  result,
1074
+ clearResult,
1075
+ fromPoint,
1053
1076
  } = useMeasure();
1054
1077
  ```
1055
1078
 
@@ -1061,6 +1084,8 @@ const {
1061
1084
  | `startMeasure` | `() => void` | Enter measurement mode (click two points) |
1062
1085
  | `cancelMeasure` | `() => void` | Exit measurement mode |
1063
1086
  | `result` | `MeasureResult \| null` | Measurement data (null if not measured yet) |
1087
+ | `clearResult` | `() => void` | Clear the current measurement result |
1088
+ | `fromPoint` | `MeasurePoint \| null` | The first picked point while measuring (null when inactive) |
1064
1089
 
1065
1090
  #### MeasureResult
1066
1091
 
@@ -1121,14 +1146,17 @@ Replay historical candles at various speeds with play/pause/step controls and pr
1121
1146
  import { useReplay } from "react-klinecharts-ui";
1122
1147
 
1123
1148
  const {
1124
- isPlaying,
1149
+ isReplaying,
1150
+ isPaused,
1125
1151
  speed,
1126
- currentIndex,
1152
+ barIndex,
1127
1153
  totalBars,
1128
- play,
1129
- pause,
1130
- stop,
1131
- step,
1154
+ startReplay,
1155
+ stopReplay,
1156
+ togglePause,
1157
+ stepForward,
1158
+ stepBackward,
1159
+ seekTo,
1132
1160
  setSpeed,
1133
1161
  } = useReplay();
1134
1162
  ```
@@ -1137,24 +1165,29 @@ const {
1137
1165
 
1138
1166
  | Property | Type | Description |
1139
1167
  |----------|------|-------------|
1140
- | `isPlaying` | `boolean` | Whether replay is running |
1141
- | `speed` | `number` | Current playback speed (0.25, 0.5, 1, 2, 4) |
1142
- | `currentIndex` | `number` | Current bar index being displayed |
1143
- | `totalBars` | `number` | Total bars in the dataset |
1144
- | `play` | `() => void` | Start replay from current position |
1145
- | `pause` | `() => void` | Pause replay (can resume with play) |
1146
- | `stop` | `() => void` | Stop replay and reset to start |
1147
- | `step` | `() => void` | Advance one bar when paused |
1148
- | `setSpeed` | `(speed: number) => void` | Set playback speed multiplier |
1168
+ | `isReplaying` | `boolean` | Whether a replay session is active |
1169
+ | `isPaused` | `boolean` | Whether the replay is currently paused |
1170
+ | `speed` | `ReplaySpeed` | Current playback speed multiplier (`1 \| 2 \| 5 \| 10`) |
1171
+ | `barIndex` | `number` | Current bar index in the replay |
1172
+ | `totalBars` | `number` | Total bars in the saved dataset |
1173
+ | `startReplay` | `() => void` | Start replaying from the beginning |
1174
+ | `stopReplay` | `() => void` | Stop replay and restore the original data |
1175
+ | `togglePause` | `() => void` | Toggle play/pause |
1176
+ | `stepForward` | `() => void` | Advance one bar while paused |
1177
+ | `stepBackward` | `() => void` | Go back one bar while paused |
1178
+ | `seekTo` | `(index: number) => void` | Seek to a specific bar index (pauses playback) |
1179
+ | `setSpeed` | `(speed: ReplaySpeed) => void` | Change the playback speed |
1149
1180
 
1150
1181
  ---
1151
1182
 
1152
1183
  ### useAlerts
1153
1184
 
1154
- Client-side price alerts. Draws a locked horizontal line on the chart for each alert and polls the latest candle once per second, firing a callback when the close price crosses the alert level. This is the primary hook for reacting to price events — e.g. forwarding a buy/sell signal to your backend or triggering a push notification (see [Backend Signals & Notifications](#backend-signals--notifications)).
1185
+ Client-side price alerts. Draws a **labelled** locked horizontal line (price tag on the Y-axis + a bell-marked caption above the line) on the chart for each alert and polls the latest candle once per second, firing a callback when the close price crosses the alert level. This is the primary hook for reacting to price events — e.g. forwarding a buy/sell signal to your backend or triggering a push notification (see [Backend Signals & Notifications](#backend-signals--notifications)).
1155
1186
 
1156
1187
  > **Multi-instance safe.** The alert list lives in the shared store (`state.alerts`) and the crossing poller is owned by the provider (one poller, active only while alerts exist), so multiple `useAlerts()` instances share one list. Note: `onAlertTriggered` registers a **single** listener — the last registration wins.
1157
1188
 
1189
+ > **No manual overlay registration.** The `alertLine` overlay template the hook draws with is registered automatically (both by `registerExtensions()` and lazily inside `useAlerts` before the first overlay is created) — you don't need to pass it through the provider's `overlays` prop.
1190
+
1158
1191
  ```typescript
1159
1192
  import { useAlerts } from "react-klinecharts-ui";
1160
1193
 
@@ -1166,8 +1199,15 @@ const {
1166
1199
  onAlertTriggered,
1167
1200
  } = useAlerts();
1168
1201
 
1202
+ // Default: orange dashed line, bell + price/message caption.
1169
1203
  const id = addAlert(65000, "crossing_up", "BTC broke 65k");
1170
1204
 
1205
+ // Customize the look via the optional 4th argument (AlertLineExtendData).
1206
+ addAlert(70000, "crossing_up", "Take profit", {
1207
+ color: "#e91e63",
1208
+ showBell: true,
1209
+ });
1210
+
1171
1211
  onAlertTriggered((alert) => {
1172
1212
  console.log("Alert fired:", alert.message, alert.price);
1173
1213
  });
@@ -1178,7 +1218,7 @@ onAlertTriggered((alert) => {
1178
1218
  | Property | Type | Description |
1179
1219
  |----------|------|-------------|
1180
1220
  | `alerts` | `Alert[]` | Current alerts (active and triggered) |
1181
- | `addAlert` | `(price: number, condition: AlertCondition, message?: string) => string` | Create an alert at a price level; returns its id |
1221
+ | `addAlert` | `(price: number, condition: AlertCondition, message?: string, extendData?: AlertLineExtendData) => string` | Create an alert at a price level; returns its id. The optional `extendData` customizes the line/label look |
1182
1222
  | `removeAlert` | `(id: string) => void` | Remove a single alert and its chart line |
1183
1223
  | `clearAlerts` | `() => void` | Remove all alerts |
1184
1224
  | `onAlertTriggered` | `(callback: (alert: Alert) => void) => void` | Register a callback fired once when an alert's condition is met |
@@ -1194,9 +1234,28 @@ interface Alert {
1194
1234
  condition: AlertCondition;
1195
1235
  message?: string;
1196
1236
  triggered: boolean;
1237
+ /** Visual style of the alert line; persisted so it survives undo/redo & layout presets. */
1238
+ extendData?: AlertLineExtendData;
1239
+ }
1240
+
1241
+ interface AlertLineExtendData {
1242
+ /** Primary color for the line, the Y-axis mark bg, and label fallback. Default: "#ff9800" */
1243
+ color?: string;
1244
+ /** Caption above the line. Defaults to `message ?? formatted price` (symbol precision). */
1245
+ text?: string;
1246
+ /** Line style overrides (style / width / dashedValue). Default: dashed. */
1247
+ line?: OrderLineLineStyle;
1248
+ /** Y-axis price mark style overrides. */
1249
+ mark?: OrderLineMarkStyle;
1250
+ /** Caption text style overrides. */
1251
+ label?: OrderLineLabelStyle;
1252
+ /** Show a 🔔 marker before the caption. Default: true */
1253
+ showBell?: boolean;
1197
1254
  }
1198
1255
  ```
1199
1256
 
1257
+ The `line` / `mark` / `label` style types are shared with [`useOrderLines`](#useorderlines) (`OrderLineLineStyle`, `OrderLineMarkStyle`, `OrderLineLabelStyle`).
1258
+
1200
1259
  | Condition | Fires when |
1201
1260
  |-----------|------------|
1202
1261
  | `crossing_up` | Previous close `<` price **and** current close `>=` price |
@@ -1271,6 +1330,83 @@ type ExportFormat = "csv" | "json";
1271
1330
 
1272
1331
  ---
1273
1332
 
1333
+ ### useHotkeys
1334
+
1335
+ Keyboard shortcuts (klinecharts v10, requires **klinecharts 10.0.0-beta3+**). Register custom hotkeys globally and toggle hotkey handling per chart. The `action` callback receives the chart instance, the keyboard event, the matched key, and the hotkey template.
1336
+
1337
+ ```typescript
1338
+ import { useHotkeys } from "react-klinecharts-ui";
1339
+
1340
+ const { registerHotkey, setHotkeysEnabled, supportedHotkeys } = useHotkeys();
1341
+
1342
+ // Register a custom shortcut — Ctrl/Cmd+L removes all overlays.
1343
+ registerHotkey({
1344
+ name: "remove-all-overlays",
1345
+ keys: ["ctrl+l", "meta+l"],
1346
+ preventDefault: true,
1347
+ action: ({ chart }) => chart.removeOverlay(),
1348
+ });
1349
+
1350
+ // Disable all built-in shortcuts except undo/redo.
1351
+ setHotkeysEnabled(true, ["undo", "redo"]);
1352
+ ```
1353
+
1354
+ #### Return type: `UseHotkeysReturn`
1355
+
1356
+ | Property | Type | Description |
1357
+ |----------|------|-------------|
1358
+ | `registerHotkey` | `(template: HotkeyTemplate) => void` | Register a custom hotkey globally (idempotent per `name`) |
1359
+ | `getHotkey` | `(name: string) => HotkeyTemplate \| null` | Look up a registered hotkey by name |
1360
+ | `supportedHotkeys` | `string[]` | Names of every registered hotkey (built-in + custom) |
1361
+ | `setHotkeysEnabled` | `(enabled: boolean, exclude?: string[]) => void` | Enable/disable hotkey handling for the chart; optionally exclude names |
1362
+ | `getHotkeysConfig` | `() => Hotkey \| null` | Current `{ enabled, exclude }` config for the chart |
1363
+
1364
+ ```typescript
1365
+ interface HotkeyTemplate {
1366
+ name: string;
1367
+ keys: string | string[];
1368
+ preventDefault?: boolean;
1369
+ stopPropagation?: boolean;
1370
+ check?: (params: HotkeyActionParams) => boolean;
1371
+ action: (params: HotkeyActionParams) => void;
1372
+ extendData?: unknown;
1373
+ }
1374
+
1375
+ interface Hotkey {
1376
+ enabled: boolean;
1377
+ exclude: string[];
1378
+ }
1379
+ ```
1380
+
1381
+ > Custom hotkeys register **globally** (shared by every chart on the page); the enable/exclude switches are per-chart. klinecharts exposes no removal API, so a registered hotkey lives for the page session.
1382
+
1383
+ ---
1384
+
1385
+ ### useChartAxes
1386
+
1387
+ Override the chart's built-in X (time) and Y (value) axes (klinecharts v10 `overrideXAxis` / `overrideYAxis`, added in **beta2**). For binding indicators to additional secondary Y-axes, use [useIndicators](#useindicators) instead.
1388
+
1389
+ ```typescript
1390
+ import { useChartAxes } from "react-klinecharts-ui";
1391
+
1392
+ const { overrideXAxis, overrideYAxis } = useChartAxes();
1393
+
1394
+ overrideYAxis({ reverse: true }); // flip the price scale
1395
+ overrideYAxis({ inside: true }); // draw price labels inside the pane
1396
+ overrideXAxis({ scrollZoomEnabled: false }); // lock time-axis zoom
1397
+ ```
1398
+
1399
+ #### Return type: `UseChartAxesReturn`
1400
+
1401
+ | Property | Type | Description |
1402
+ |----------|------|-------------|
1403
+ | `overrideXAxis` | `(override: XAxisOverride) => void` | Override the main X (time) axis (`name`, `scrollZoomEnabled`, `createTicks`) |
1404
+ | `overrideYAxis` | `(override: YAxisOverride) => void` | Override a Y (value) axis (`reverse`, `inside`, `position`, `scrollZoomEnabled`, `createRange`, `createTicks`, `id`/`paneId` to target one) |
1405
+
1406
+ > klinecharts beta3 ships these two methods with their parameter types **crossed** in its published typings; this hook shields you behind semantically-correct signatures, so `overrideYAxis` takes `YAxisOverride` and `overrideXAxis` takes `XAxisOverride` as expected.
1407
+
1408
+ ---
1409
+
1274
1410
  ## Utilities
1275
1411
 
1276
1412
  ### createDataLoader
@@ -1513,7 +1649,7 @@ import { indicators } from "react-klinecharts-ui";
1513
1649
 
1514
1650
  ### registerExtensions
1515
1651
 
1516
- Registers all built-in drawing overlays via `registerOverlay`. Called automatically by the provider when `registerExtensions: true`.
1652
+ Registers all built-in drawing overlays plus the feature overlays (`orderLine`, `alertLine`, `depthOverlay`) via `registerOverlay`. Called automatically by the provider when `registerExtensions: true`.
1517
1653
 
1518
1654
  ```typescript
1519
1655
  import { registerExtensions } from "react-klinecharts-ui";
@@ -1522,12 +1658,11 @@ registerExtensions(); // Idempotent — repeated calls are ignored
1522
1658
 
1523
1659
  ### orderLine
1524
1660
 
1525
- Overlay template for horizontal price level lines. **Not registered automatically** must be passed explicitly to the provider.
1661
+ Overlay template for horizontal price level lines. **Registered automatically** by `registerExtensions()` (default), so `useOrderLines` works out of the box. Passing it through `overlays={[orderLine]}` is optional.
1526
1662
 
1527
1663
  ```typescript
1528
- import { orderLine, KlinechartsUIProvider } from "react-klinecharts-ui";
1529
-
1530
- <KlinechartsUIProvider overlays={[orderLine]}>...</KlinechartsUIProvider>;
1664
+ import { orderLine } from "react-klinecharts-ui";
1665
+ // No provider wiring needed — registered automatically.
1531
1666
  ```
1532
1667
 
1533
1668
  **Implementation details:**
@@ -1593,14 +1728,24 @@ interface OrderLinePadding {
1593
1728
 
1594
1729
  All sub-interfaces (`OrderLineLineStyle`, `OrderLineMarkStyle`, `OrderLineLabelStyle`, `OrderLineFontStyle`, `OrderLinePadding`) are exported as named types from both the main and `extensions` entry points.
1595
1730
 
1596
- ### depthOverlay
1731
+ ### alertLine
1597
1732
 
1598
- Overlay template for visualizing order book depth as horizontal liquidity bars at each price level. Shows cumulative buy/sell volume at price levels, useful for understanding support/resistance zones.
1733
+ Overlay template drawn by [`useAlerts`](#usealerts) for price alerts: a locked horizontal line with a Y-axis price mark and a bell-marked caption above the line. **Registered automatically** by `registerExtensions()` and lazily by `useAlerts` itself, so no provider wiring is required.
1599
1734
 
1600
1735
  ```typescript
1601
- import { depthOverlay, KlinechartsUIProvider } from "react-klinecharts-ui/extensions";
1736
+ import { alertLine } from "react-klinecharts-ui";
1737
+ // Used internally by useAlerts; exported for advanced/manual overlay use.
1738
+ ```
1602
1739
 
1603
- <KlinechartsUIProvider overlays={[depthOverlay]}>...</KlinechartsUIProvider>;
1740
+ Its `extendData` shape is [`AlertLineExtendData`](#types) — it reuses the `OrderLineLineStyle` / `OrderLineMarkStyle` / `OrderLineLabelStyle` sub-types from `orderLine` and adds `showBell?: boolean` (default `true`). When no `text` is supplied the caption falls back to the formatted price (using `chart.getSymbol()?.pricePrecision`).
1741
+
1742
+ ### depthOverlay
1743
+
1744
+ Overlay template for visualizing order book depth as horizontal liquidity bars at each price level. Shows cumulative buy/sell volume at price levels, useful for understanding support/resistance zones. **Registered automatically** by `registerExtensions()` (default); explicit `overlays={[depthOverlay]}` wiring is optional.
1745
+
1746
+ ```typescript
1747
+ import { depthOverlay } from "react-klinecharts-ui/extensions";
1748
+ // No provider wiring needed — registered automatically.
1604
1749
  ```
1605
1750
 
1606
1751
  **Implementation details:**
@@ -1926,7 +2071,7 @@ export {
1926
2071
  export * from "./indicators";
1927
2072
 
1928
2073
  // Extensions
1929
- export { registerExtensions, overlays, indicators, orderLine, depthOverlay };
2074
+ export { registerExtensions, overlays, indicators, orderLine, alertLine, depthOverlay };
1930
2075
  export type {
1931
2076
  OrderLineExtendData,
1932
2077
  OrderLineLineStyle,
@@ -1934,6 +2079,7 @@ export type {
1934
2079
  OrderLineLabelStyle,
1935
2080
  OrderLineFontStyle,
1936
2081
  OrderLinePadding,
2082
+ AlertLineExtendData,
1937
2083
  DepthOverlayExtendData,
1938
2084
  DepthOverlayRow,
1939
2085
  };
@@ -2443,19 +2443,134 @@ var depthOverlay = {
2443
2443
  };
2444
2444
  var depthOverlay_default = depthOverlay;
2445
2445
 
2446
+ // src/extensions/overlays/alertLine.ts
2447
+ var DEFAULT_FONT_FAMILY2 = "Helvetica Neue, Arial, sans-serif";
2448
+ var DEFAULT_COLOR = "#ff9800";
2449
+ var BELL_MARK = "\u{1F514}";
2450
+ var alertLine = {
2451
+ name: "alertLine",
2452
+ totalStep: 2,
2453
+ needDefaultPointFigure: false,
2454
+ needDefaultXAxisFigure: false,
2455
+ needDefaultYAxisFigure: false,
2456
+ createYAxisFigures: ({ chart, overlay, coordinates }) => {
2457
+ if (coordinates.length < 1) return [];
2458
+ const y = coordinates[0].y;
2459
+ const price = overlay.points[0]?.value;
2460
+ if (price == null) return [];
2461
+ const d = overlay.extendData ?? {};
2462
+ const color = d.color ?? DEFAULT_COLOR;
2463
+ const m = d.mark;
2464
+ const precision = chart.getSymbol()?.pricePrecision ?? 2;
2465
+ return [
2466
+ {
2467
+ type: "text",
2468
+ attrs: {
2469
+ x: 0,
2470
+ y,
2471
+ text: price.toFixed(precision),
2472
+ align: "left",
2473
+ baseline: "middle"
2474
+ },
2475
+ styles: {
2476
+ color: m?.color ?? "#ffffff",
2477
+ size: m?.font?.size ?? 11,
2478
+ family: m?.font?.family ?? DEFAULT_FONT_FAMILY2,
2479
+ weight: m?.font?.weight ?? "bold",
2480
+ paddingLeft: m?.padding?.x ?? 4,
2481
+ paddingRight: m?.padding?.x ?? 4,
2482
+ paddingTop: m?.padding?.y ?? 4,
2483
+ paddingBottom: m?.padding?.y ?? 4,
2484
+ backgroundColor: m?.bg ?? color,
2485
+ borderRadius: m?.borderRadius ?? 2
2486
+ }
2487
+ }
2488
+ ];
2489
+ },
2490
+ createPointFigures: ({ chart, coordinates, bounding, overlay }) => {
2491
+ if (coordinates.length < 1) return [];
2492
+ const y = coordinates[0].y;
2493
+ const d = overlay.extendData ?? {};
2494
+ const color = d.color ?? DEFAULT_COLOR;
2495
+ const ln = d.line;
2496
+ const figures = [
2497
+ {
2498
+ type: "line",
2499
+ attrs: {
2500
+ coordinates: [
2501
+ { x: 0, y },
2502
+ { x: bounding.width, y }
2503
+ ]
2504
+ },
2505
+ styles: {
2506
+ style: ln?.style ?? "dashed",
2507
+ color,
2508
+ size: ln?.width ?? 1,
2509
+ dashedValue: ln?.dashedValue ?? [4, 2]
2510
+ }
2511
+ }
2512
+ ];
2513
+ const price = overlay.points[0]?.value;
2514
+ const precision = chart.getSymbol()?.pricePrecision ?? 2;
2515
+ const baseText = d.text ?? (price != null ? price.toFixed(precision) : "");
2516
+ const showBell = d.showBell ?? true;
2517
+ const text = baseText ? showBell ? `${BELL_MARK} ${baseText}` : baseText : showBell ? BELL_MARK : "";
2518
+ if (text) {
2519
+ const lb = d.label;
2520
+ figures.push({
2521
+ type: "text",
2522
+ ignoreEvent: true,
2523
+ attrs: {
2524
+ x: lb?.offset?.x ?? 8,
2525
+ y: y - (lb?.offset?.y ?? 3),
2526
+ text,
2527
+ align: "left",
2528
+ baseline: "bottom"
2529
+ },
2530
+ styles: {
2531
+ color: lb?.color ?? color,
2532
+ size: lb?.font?.size ?? 11,
2533
+ family: lb?.font?.family ?? DEFAULT_FONT_FAMILY2,
2534
+ weight: lb?.font?.weight ?? "normal",
2535
+ paddingLeft: lb?.padding?.x ?? 0,
2536
+ paddingRight: lb?.padding?.x ?? 0,
2537
+ paddingTop: lb?.padding?.y ?? 0,
2538
+ paddingBottom: lb?.padding?.y ?? 0,
2539
+ backgroundColor: lb?.bg ?? "transparent",
2540
+ borderRadius: lb?.borderRadius ?? 0
2541
+ }
2542
+ });
2543
+ }
2544
+ return figures;
2545
+ },
2546
+ performEventPressedMove: ({ points, performPoint }) => {
2547
+ points[0].value = performPoint.value;
2548
+ }
2549
+ };
2550
+ var alertLine_default = alertLine;
2551
+
2446
2552
  // src/extensions/index.ts
2447
2553
  var overlays = Object.values(overlays_exports);
2554
+ var featureOverlays = [orderLine_default, depthOverlay_default, alertLine_default];
2448
2555
  var indicators = Object.values(indicators_exports);
2449
2556
  var registered = false;
2450
2557
  function registerExtensions() {
2451
2558
  if (registered) return;
2452
2559
  overlays.forEach((overlay) => reactKlinecharts.registerOverlay(overlay));
2560
+ featureOverlays.forEach((overlay) => reactKlinecharts.registerOverlay(overlay));
2453
2561
  indicators.forEach((indicator) => reactKlinecharts.registerIndicator(indicator));
2454
2562
  registered = true;
2455
2563
  }
2564
+ var alertLineRegistered = false;
2565
+ function ensureAlertLineRegistered() {
2566
+ if (alertLineRegistered) return;
2567
+ reactKlinecharts.registerOverlay(alertLine_default);
2568
+ alertLineRegistered = true;
2569
+ }
2456
2570
 
2457
2571
  exports.TA_default = TA_default;
2458
2572
  exports.abcd_default = abcd_default;
2573
+ exports.alertLine_default = alertLine_default;
2459
2574
  exports.anyWaves_default = anyWaves_default;
2460
2575
  exports.arrow_default = arrow_default;
2461
2576
  exports.bollTv_default = bollTv_default;
@@ -2465,6 +2580,8 @@ exports.circle_default = circle_default;
2465
2580
  exports.depthOverlay_default = depthOverlay_default;
2466
2581
  exports.eightWaves_default = eightWaves_default;
2467
2582
  exports.elliottWave_default = elliottWave_default;
2583
+ exports.ensureAlertLineRegistered = ensureAlertLineRegistered;
2584
+ exports.featureOverlays = featureOverlays;
2468
2585
  exports.fibRetracement_default = fibRetracement_default;
2469
2586
  exports.fibonacciCircle_default = fibonacciCircle_default;
2470
2587
  exports.fibonacciExtension_default = fibonacciExtension_default;
@@ -2497,5 +2614,5 @@ exports.threeWaves_default = threeWaves_default;
2497
2614
  exports.triangle_default = triangle_default;
2498
2615
  exports.vwap_default = vwap_default;
2499
2616
  exports.xabcd_default = xabcd_default;
2500
- //# sourceMappingURL=chunk-UJNJH3BS.cjs.map
2501
- //# sourceMappingURL=chunk-UJNJH3BS.cjs.map
2617
+ //# sourceMappingURL=chunk-FSHI2ZDB.cjs.map
2618
+ //# sourceMappingURL=chunk-FSHI2ZDB.cjs.map