@rioaxyz/sonrchart 0.1.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.
@@ -0,0 +1,1116 @@
1
+ import * as react from 'react';
2
+ import { RefObject, ReactNode, CSSProperties, ButtonHTMLAttributes } from 'react';
3
+ import { Point, Nullable, DeepPartial, OverlayStyle, OverlayMode, Chart, KLineData, Styles, PeriodType, OverlayCreateFiguresCallbackParams, OverlayFigure, Coordinate } from 'klinecharts';
4
+
5
+ /** One saved overlay in a drawing template — the canonical serialized shape of
6
+ * a user drawing, shared by ChartState.drawings and SonrChart's snapshot/
7
+ * restore. Field types mirror KLineChart's `Overlay`, so a snapshot round-trips
8
+ * straight back into `createOverlay` with no casts. */
9
+ interface DrawingSnapshotItem {
10
+ name: string;
11
+ points: Array<Partial<Point>>;
12
+ styles?: Nullable<DeepPartial<OverlayStyle>>;
13
+ mode?: OverlayMode;
14
+ extendData?: unknown;
15
+ }
16
+ /** A full drawing template: the user overlays captured at save time. */
17
+ type DrawingSnapshot = DrawingSnapshotItem[];
18
+ /** Named-drawing-set store with change subscription (for a settings UI). */
19
+ declare class DrawingTemplateStore {
20
+ private templates;
21
+ private subs;
22
+ /** Save (or overwrite) a named template from a drawing snapshot. */
23
+ save(name: string, snap: DrawingSnapshot): void;
24
+ /** The saved snapshot for a name, or undefined if there is none. */
25
+ get(name: string): DrawingSnapshot | undefined;
26
+ /** Names of all saved templates, in insertion order. */
27
+ list(): string[];
28
+ /** Remove a template. No-op if the name is unknown. */
29
+ delete(name: string): void;
30
+ /** Subscribe to list changes (save/delete). Returns an unsubscribe fn. */
31
+ subscribe(cb: () => void): () => void;
32
+ private notify;
33
+ }
34
+
35
+ /** One OHLC(V) bar. `time` is milliseconds since the Unix epoch. */
36
+ interface Bar {
37
+ time: number;
38
+ open: number;
39
+ high: number;
40
+ low: number;
41
+ close: number;
42
+ volume?: number;
43
+ }
44
+ /** Chart interval token. Seconds ("10S"/"30S"), minutes ("1".."30"),
45
+ * hour ("60"), or daily ("D"). Host apps may pass any string a matching
46
+ * DataSource understands; these are what the built-in period mapping knows. */
47
+ type Interval = "10S" | "30S" | "1" | "5" | "15" | "30" | "60" | "D" | (string & {});
48
+ /** Resolved metadata for a symbol (issue #8). All fields optional except the
49
+ * ticker; the host supplies whatever it knows. */
50
+ interface SymbolInfo {
51
+ ticker: string;
52
+ name?: string;
53
+ /** Decimal places for prices; drives the y-axis format. */
54
+ pricePrecision?: number;
55
+ /** Decimal places for volume. */
56
+ volumePrecision?: number;
57
+ /** ISO currency code or symbol prices are quoted in (e.g. "USD", "$", "€").
58
+ * Prefixed to prices in the legend / crosshair pill. */
59
+ currency?: string;
60
+ /** Unit prices are quoted in (e.g. "pts", "¢", "bps"). Suffixed to prices. */
61
+ unit?: string;
62
+ /** URL (or data URI) for the symbol's logo, shown in the info dialog + legend. */
63
+ logo?: string;
64
+ /** URL (or data URI) for the listing exchange's logo. */
65
+ exchangeLogo?: string;
66
+ /** Long-form description of the instrument, shown in the info dialog. */
67
+ description?: string;
68
+ /** Where the price data originates (e.g. "Alpaca", "IEX"), shown in the dialog. */
69
+ priceSource?: string;
70
+ }
71
+ /** One hit from a symbol search (issue #37). Only `symbol` is required; the
72
+ * datafeed supplies whatever else it knows to help the user disambiguate. */
73
+ interface SymbolSearchResult {
74
+ symbol: string;
75
+ name?: string;
76
+ exchange?: string;
77
+ type?: string;
78
+ /** URL (or data URI) for the symbol's logo, shown beside the result (#39). */
79
+ logo?: string;
80
+ }
81
+ /**
82
+ * How sonrchart gets its data. This is the whole integration seam: the
83
+ * component knows nothing about where bars come from, so any host — a REST
84
+ * API, a websocket, a local file, synthetic data — implements this.
85
+ */
86
+ interface DataSource {
87
+ /** Return the most-recent `count` bars for a symbol/interval, oldest→newest. */
88
+ getBars(symbol: string, interval: Interval, count: number): Promise<Bar[]>;
89
+ /**
90
+ * Optional live feed. Call `onBar` for every new/updated bar (forming or
91
+ * closed). Return an unsubscribe function. Omit for a static chart.
92
+ */
93
+ subscribe?(symbol: string, interval: Interval, onBar: (bar: Bar) => void): () => void;
94
+ /**
95
+ * Optional symbol resolution (issue #8). Validate/enrich a ticker before it
96
+ * loads. Return `null` for an unknown symbol (the chart fires `onSymbolError`
97
+ * and skips loading), or a SymbolInfo to set precision/name.
98
+ */
99
+ resolveSymbol?(symbol: string): Promise<SymbolInfo | null>;
100
+ /**
101
+ * Optional symbol search (issue #37). Given a partial query, return matching
102
+ * symbols for a search-as-you-type dialog. Omit if the datafeed can't search
103
+ * (the SymbolSearch component degrades gracefully).
104
+ */
105
+ searchSymbols?(query: string): Promise<SymbolSearchResult[]>;
106
+ }
107
+ /** Price-scale configuration (issue #12). */
108
+ interface PriceScale {
109
+ /** "normal" (default), "percentage" (% change), or "logarithm". */
110
+ type?: "normal" | "percentage" | "logarithm";
111
+ /** Flip the axis so price increases downward. */
112
+ invert?: boolean;
113
+ /** Draw the y-axis labels inside the plot area. */
114
+ inside?: boolean;
115
+ }
116
+ /** Price-scale labels shown on the y-axis (issue #41 — labels). Each toggles a
117
+ * KLineChart price mark. `undefined` fields keep the current value. */
118
+ interface PriceLabels {
119
+ /** The last-price value pill on the axis. */
120
+ lastValue?: boolean;
121
+ /** The horizontal line drawn across the chart at the last price. */
122
+ lastLine?: boolean;
123
+ /** The visible-range high price mark. */
124
+ high?: boolean;
125
+ /** The visible-range low price mark. */
126
+ low?: boolean;
127
+ /** Countdown to the current bar's close, under the last-price pill. */
128
+ countdown?: boolean;
129
+ }
130
+ /** Crosshair/drawing magnet mode (issue #13). `true` = weak. */
131
+ type Magnet = boolean | "weak" | "strong";
132
+ /** Candle rendering style (issue #1). "heikin_ashi" transforms the data. */
133
+ type CandleStyle = "candle" | "hollow" | "hollow_up" | "ohlc" | "area" | "heikin_ashi" | "line" | "step" | "baseline" | "column" | "hlc" | "high_low";
134
+ /** A comparison symbol overlaid on the main pane (issue #9). */
135
+ interface CompareSpec {
136
+ symbol: string;
137
+ color?: string;
138
+ }
139
+ /** A KLineChart drawing-tool name (issue #3). */
140
+ type DrawingTool = "segment" | "rayLine" | "straightLine" | "horizontalStraightLine" | "verticalStraightLine" | "priceLine" | "priceChannelLine" | "parallelStraightLine" | "fibonacciLine" | "simpleAnnotation" | "simpleTag" | "text" | "brush" | "highlighter" | "rectangle" | "ellipse" | "triangle" | "priceRange" | "riskReward" | "horizontalRay" | "crossLine" | "arrow" | "fibExtension" | "fibTimeZone" | "dateRange" | "datePriceRange";
141
+ /** One active indicator row for the data-window panel (#45). */
142
+ interface IndicatorRow {
143
+ name: string;
144
+ visible: boolean;
145
+ }
146
+ /** One user-drawing row for the object-tree panel (#45). */
147
+ interface DrawingRow {
148
+ /** Overlay id — the stable handle for per-drawing operations. */
149
+ id: string;
150
+ /** Raw overlay/tool name (e.g. "segment", "sonrBrush", "text"). */
151
+ name: string;
152
+ /** Human label (tool name, or the text content for a text label). */
153
+ label: string;
154
+ visible: boolean;
155
+ locked: boolean;
156
+ }
157
+ /** Serialized chart state for save/load (issue #15). Opaque JSON the host
158
+ * persists and hands back to `importState`. */
159
+ interface ChartState {
160
+ version: 1;
161
+ drawings: DrawingSnapshotItem[];
162
+ indicators: Array<{
163
+ name: string;
164
+ paneId?: string;
165
+ }>;
166
+ priceScale?: PriceScale;
167
+ }
168
+ /** A horizontal reference line drawn across the chart (e.g. a trade plan's
169
+ * entry / stop / target). Static — see OrderLine for draggable lines. */
170
+ interface PriceLine {
171
+ price: number;
172
+ color?: string;
173
+ /** Short label drawn at the line, e.g. "Entry", "Stop", "Target". */
174
+ label?: string;
175
+ /** "solid" (default) | "dashed". */
176
+ style?: "solid" | "dashed";
177
+ }
178
+ /**
179
+ * A draggable on-chart order/position line (issue #19). Like PriceLine but the
180
+ * user can drag it to a new price; `onMove` fires with the new price when the
181
+ * drag ends (and continuously if `live`).
182
+ */
183
+ interface OrderLine {
184
+ /** Stable id so React reconciliation and callbacks can identify the line. */
185
+ id: string;
186
+ price: number;
187
+ color?: string;
188
+ label?: string;
189
+ style?: "solid" | "dashed";
190
+ /** Allow dragging. Default true (that's the point of an OrderLine). */
191
+ draggable?: boolean;
192
+ /** Fires with the new price. `phase` is "moving" during the drag and "end"
193
+ * when released. */
194
+ onMove?: (price: number, phase: "moving" | "end") => void;
195
+ }
196
+ /**
197
+ * How to add one technical indicator (issue #4). A bare string is shorthand
198
+ * for `{ name }`.
199
+ */
200
+ interface IndicatorSpec {
201
+ /** KLineChart indicator name, e.g. "VOL", "MACD", "RSI", "BOLL", "MA". */
202
+ name: string;
203
+ /** "main" overlays it on the price pane; "new" (default) gives it a sub-pane. */
204
+ pane?: "main" | "new";
205
+ /** Indicator calc params, e.g. [5, 10, 20] for MA. */
206
+ calcParams?: number[];
207
+ }
208
+ /** A pattern-context marker drawn on the price pane (issue #5) — Sonr's own
209
+ * custom indicator. Marks where a setup triggered. */
210
+ interface PatternMarker {
211
+ /** Bar time (epoch ms) to anchor the marker to. */
212
+ time: number;
213
+ /** "long" draws below the bar pointing up; "short" above pointing down. */
214
+ kind?: "long" | "short";
215
+ /** Optional short label (e.g. the pattern name). */
216
+ label?: string;
217
+ color?: string;
218
+ }
219
+ /** Session background tinting (issue #10). `true` uses the default palette;
220
+ * pass an object to override the pre/after-hours tints (regular hours are
221
+ * untinted). Colors should be low-alpha so candles read through. */
222
+ type SessionTint = boolean | {
223
+ premarket?: string;
224
+ afterhours?: string;
225
+ };
226
+ type Theme = "dark" | "light";
227
+ /** Watermark configuration (issue: watermark controls). Show the symbol and/or
228
+ * the interval, with a configurable color and opacity. */
229
+ interface WatermarkOptions {
230
+ symbol: boolean;
231
+ interval: boolean;
232
+ /** #rrggbb ink color (opacity applied separately). */
233
+ color: string;
234
+ /** 0..1. */
235
+ opacity: number;
236
+ }
237
+
238
+ declare const BRUSH_OVERLAY = "sonrBrush";
239
+ interface BrushStyle {
240
+ color: string;
241
+ size: number;
242
+ }
243
+ /** The two brush tools, keyed to the drawing-toolbar tool ids. */
244
+ type BrushTool = "brush" | "highlighter";
245
+
246
+ declare const TEXT_OVERLAY = "text";
247
+ /** Styling for a text label (defaults for new labels live on the chart handle). */
248
+ interface TextStyle {
249
+ color: string;
250
+ size: number;
251
+ }
252
+ /** Shape of a text overlay's extendData: the label plus its per-label style. */
253
+ interface TextData extends Partial<TextStyle> {
254
+ text: string;
255
+ }
256
+ declare function registerTextOverlay(): void;
257
+
258
+ interface SonrChartProps {
259
+ symbol: string;
260
+ interval?: Interval;
261
+ dataSource: DataSource;
262
+ /** "dark" | "light", or the name of a theme registered via `registerTheme`
263
+ * or supplied in `customThemes`. (#46) */
264
+ theme?: Theme | string;
265
+ /** Inline named custom themes, looked up before the global registry. (#46) */
266
+ customThemes?: Record<string, DeepPartial<Styles>>;
267
+ styles?: DeepPartial<Styles>;
268
+ /** Indicators to show. Strings ("VOL") or specs. Default ["VOL"]. (#4) */
269
+ indicators?: (string | IndicatorSpec)[];
270
+ /** Per-indicator sub-pane heights in px, keyed by indicator name. (#7) */
271
+ paneHeights?: Record<string, number>;
272
+ /** Session background tinting for pre/after-hours. (#10) */
273
+ sessions?: SessionTint;
274
+ /** Underlaid symbol + interval watermark behind the candles. `true` shows both;
275
+ * pass options to toggle each and set color/opacity. */
276
+ watermark?: boolean | Partial<WatermarkOptions>;
277
+ /** Pattern-context markers on the price pane. (#5) */
278
+ patterns?: PatternMarker[];
279
+ /** Static reference lines (entry / stop / target). */
280
+ priceLines?: PriceLine[];
281
+ /** Draggable order/position lines. (#19) */
282
+ orderLines?: OrderLine[];
283
+ /** Price-scale mode (log / percentage / invert / inside). (#12) */
284
+ priceScale?: PriceScale;
285
+ /** Price-scale labels (last value/line, high/low marks). (#41) */
286
+ priceLabels?: Partial<PriceLabels>;
287
+ /** Magnet mode for drawing tools — snap points to nearby OHLC. (#13) */
288
+ magnet?: Magnet;
289
+ /** Candle rendering style — solid/hollow/ohlc/area/heikin_ashi. (#1) */
290
+ candleStyle?: CandleStyle;
291
+ /** Comparison symbols overlaid on the main pane, ratio-scaled. (#9) */
292
+ compareSeries?: CompareSpec[];
293
+ /** How many bars to request on load. Default 500. */
294
+ barCount?: number;
295
+ /** Enable built-in keyboard shortcuts when the chart is focused. (#14)
296
+ * Default true. See `onShortcut` to observe/extend them. */
297
+ keyboard?: boolean;
298
+ /** Called for every recognized shortcut ("escape" | "undo" | "redo" |
299
+ * "delete") while the chart is focused, even when the built-in also runs —
300
+ * a host can observe or extend the behavior. (#14) */
301
+ onShortcut?: (action: string, e: KeyboardEvent) => void;
302
+ /** Override the crosshair price pill / big-number formatting. (#46) */
303
+ priceFormatter?: (value: number) => string;
304
+ /** Override the crosshair date template, e.g. "YYYY-MM-DD HH:mm". (#46) */
305
+ dateFormat?: string;
306
+ /** IANA timezone for the x-axis + crosshair time (#38). Default
307
+ * "America/New_York". Also settable via the handle / <TimezoneMenu>. */
308
+ timezone?: string;
309
+ /** Data-source label shown in the candle legend header (e.g. "Alpaca"),
310
+ * after `symbol · interval`, TradingView-style. */
311
+ source?: string;
312
+ /** Show the built-in canvas candle legend (O/H/L/C/…). Default true. Set false
313
+ * when rendering your own header via <ChartHeader> + `subscribeHeaderBar`. */
314
+ legend?: boolean;
315
+ onReady?: (chart: Chart) => void;
316
+ /** Fired when resolveSymbol returns null for the requested ticker. (#8) */
317
+ onSymbolError?: (symbol: string) => void;
318
+ className?: string;
319
+ style?: React.CSSProperties;
320
+ }
321
+ /** Imperative surface: raw chart, indicator control (#4), drawing tools (#3),
322
+ * price scale (#12), snapshot (#20), and state save/load (#15). */
323
+ interface SonrChartHandle {
324
+ chart(): Chart | null;
325
+ addIndicator(spec: string | IndicatorSpec): void;
326
+ removeIndicator(name: string): void;
327
+ listIndicators(): string[];
328
+ /** Start interactive drawing of a tool; honors the current magnet mode. */
329
+ startDrawing(tool: DrawingTool): void;
330
+ /** Cancel an armed-but-unplaced drawing (toggle the tool off). */
331
+ cancelDrawing(): void;
332
+ /** The tool currently armed for drawing, or null if none. */
333
+ activeDrawing(): DrawingTool | null;
334
+ /** Subscribe to armed-tool changes (arm → tool, placed/cancelled → null).
335
+ * Returns an unsubscribe fn. Lets a toolbar highlight the active tool. */
336
+ subscribeDrawing(cb: (tool: DrawingTool | null) => void): () => void;
337
+ /** Remove all user-drawn overlays (leaves price/order lines + indicators). */
338
+ clearDrawings(): void;
339
+ /** Capture the chart to a data URL (PNG by default). */
340
+ snapshot(opts?: {
341
+ type?: "png" | "jpeg";
342
+ background?: string;
343
+ includeOverlays?: boolean;
344
+ }): string | null;
345
+ /** Serialize user drawings + indicators + price scale (#15). */
346
+ exportState(): ChartState;
347
+ /** Restore state produced by exportState (#15). */
348
+ importState(state: ChartState): void;
349
+ /** Current indicator set as specs — a study template to name/persist (#6). */
350
+ getIndicatorSet(): IndicatorSpec[];
351
+ /** Replace the user indicators with a saved set (#6). */
352
+ applyIndicatorSet(specs: (string | IndicatorSpec)[]): void;
353
+ /** Undo the last drawing change (#16). */
354
+ undo(): void;
355
+ /** Redo an undone drawing change (#16). */
356
+ redo(): void;
357
+ canUndo(): boolean;
358
+ canRedo(): boolean;
359
+ /** Subscribe to undo/redo-availability changes (#16). Returns unsubscribe. */
360
+ subscribeHistory(cb: () => void): () => void;
361
+ /** Current magnet mode for new drawings (#13). */
362
+ getMagnet(): Magnet | undefined;
363
+ /** Set the magnet mode imperatively (a changed `magnet` prop still overrides). */
364
+ setMagnet(magnet: Magnet | undefined): void;
365
+ /** Subscribe to magnet-mode changes. Returns unsubscribe. */
366
+ subscribeMagnet(cb: (magnet: Magnet | undefined) => void): () => void;
367
+ /** Current theme selector ("dark"/"light" or a registered/custom name). (#46) */
368
+ getTheme(): Theme | string;
369
+ /** Apply a theme by name imperatively (a changed `theme` prop still wins). (#46) */
370
+ setTheme(theme: Theme | string): void;
371
+ subscribeTheme(cb: (theme: Theme | string) => void): () => void;
372
+ /** Current IANA timezone for the x-axis + crosshair time (#38). */
373
+ getTimezone(): string;
374
+ /** Set the timezone imperatively (a changed `timezone` prop still wins). (#38) */
375
+ setTimezone(tz: string): void;
376
+ subscribeTimezone(cb: (tz: string) => void): () => void;
377
+ getCandleStyle(): CandleStyle;
378
+ setCandleStyle(style: CandleStyle): void;
379
+ subscribeCandleStyle(cb: (style: CandleStyle) => void): () => void;
380
+ getPriceScale(): PriceScale | undefined;
381
+ setPriceScale(scale: PriceScale): void;
382
+ subscribePriceScale(cb: (scale: PriceScale) => void): () => void;
383
+ getSessions(): SessionTint | undefined;
384
+ setSessions(on: SessionTint): void;
385
+ subscribeSessions(cb: (on: SessionTint) => void): () => void;
386
+ getWatermark(): WatermarkOptions;
387
+ setWatermark(opts: boolean | Partial<WatermarkOptions>): void;
388
+ subscribeWatermark(cb: () => void): () => void;
389
+ /** Current price-scale label toggles (#41). */
390
+ getPriceLabels(): Required<PriceLabels>;
391
+ /** Toggle price-scale labels (merges over the current set). */
392
+ setPriceLabels(opts: Partial<PriceLabels>): void;
393
+ subscribePriceLabels(cb: () => void): () => void;
394
+ /** Current brush/highlighter stroke style (color + width). */
395
+ getBrushStyle(tool: BrushTool): BrushStyle;
396
+ /** Set the brush/highlighter stroke style — applies to subsequent strokes. */
397
+ setBrushStyle(tool: BrushTool, style: BrushStyle): void;
398
+ /** Subscribe to brush-style changes (for a settings UI). Returns unsubscribe. */
399
+ subscribeBrush(cb: () => void): () => void;
400
+ /** Default color/size applied to new text labels. */
401
+ getTextStyle(): TextStyle;
402
+ setTextStyle(style: TextStyle): void;
403
+ subscribeTextStyle(cb: () => void): () => void;
404
+ /** Lock every user drawing (non-interactive) or unlock them. New drawings
405
+ * inherit the current lock state. */
406
+ setDrawingsLocked(locked: boolean): void;
407
+ /** Whether user drawings are currently locked. */
408
+ getDrawingsLocked(): boolean;
409
+ /** Show/hide every user drawing at once. New drawings inherit visibility. */
410
+ setDrawingsVisible(visible: boolean): void;
411
+ /** Whether user drawings are currently visible. */
412
+ getDrawingsVisible(): boolean;
413
+ /** Subscribe to hide/show-all changes (#35). Returns unsubscribe. */
414
+ subscribeDrawingsVisible(cb: (visible: boolean) => void): () => void;
415
+ /** Save the current user drawings as a named template (in-memory). */
416
+ saveDrawingTemplate(name: string): void;
417
+ /** Replace the current user drawings with a saved template's set. */
418
+ applyDrawingTemplate(name: string): void;
419
+ /** Names of all saved drawing templates. */
420
+ listDrawingTemplates(): string[];
421
+ /** Delete a saved drawing template. */
422
+ deleteDrawingTemplate(name: string): void;
423
+ /** Subscribe to drawing-template list changes. Returns unsubscribe. */
424
+ subscribeDrawingTemplates(cb: () => void): () => void;
425
+ /** Duplicate the most-recently-added user drawing (same points/style). */
426
+ cloneLastDrawing(): void;
427
+ /** Active user indicators as data-window rows (excludes internal overlays). */
428
+ listIndicatorRows(): IndicatorRow[];
429
+ /** Show/hide one indicator by name. */
430
+ setIndicatorVisible(name: string, visible: boolean): void;
431
+ /** Subscribe to indicator add/remove/visibility changes. Returns unsubscribe. */
432
+ subscribeIndicators(cb: () => void): () => void;
433
+ /** Every user drawing as object-tree rows (id/label/visible/locked). */
434
+ listDrawings(): DrawingRow[];
435
+ /** Show/hide one drawing by id. */
436
+ setDrawingVisible(id: string, visible: boolean): void;
437
+ /** Lock/unlock one drawing by id. */
438
+ setDrawingLocked(id: string, locked: boolean): void;
439
+ /** Remove one drawing by id. */
440
+ removeDrawing(id: string): void;
441
+ /** Scroll the chart so the drawing with this id is in view (#45). */
442
+ locateDrawing(id: string): void;
443
+ /** Change a drawing's stacking order: front/back (extreme) or forward/
444
+ * backward (one step). */
445
+ setDrawingZOrder(id: string, mode: "front" | "back" | "forward" | "backward"): void;
446
+ /** Copy a drawing to the clipboard. */
447
+ copyDrawing(id: string): void;
448
+ /** Paste the copied drawing as a new drawing. */
449
+ pasteDrawing(): void;
450
+ /** Whether a copied drawing is available to paste. */
451
+ canPasteDrawing(): boolean;
452
+ /** Id of the drawing selected on the chart (clicked), or null. */
453
+ getSelectedDrawing(): string | null;
454
+ /** Zoom the visible window to the most recent `ms` of loaded data at the
455
+ * current resolution (clamped to what's loaded). `Infinity` fits all data. */
456
+ setVisibleDuration(ms: number): void;
457
+ /** Scroll the visible window to the bar at (or nearest before) this epoch-ms. */
458
+ scrollToTimestamp(timestamp: number): void;
459
+ /** Jump the visible window to the latest (realtime) bar. */
460
+ scrollToRealTime(): void;
461
+ /** Zoom the visible range in one step (toward more detail). */
462
+ zoomIn(): void;
463
+ /** Zoom the visible range out one step (toward more history). */
464
+ zoomOut(): void;
465
+ /** Subscribe to the bar a custom header should show — the hovered bar while
466
+ * the crosshair is active, else the latest bar (updates on each streamed
467
+ * bar). Emits once immediately. Returns unsubscribe. (#45) */
468
+ subscribeHeaderBar(cb: (current: KLineData | null, prev: KLineData | null) => void): () => void;
469
+ }
470
+ declare const SonrChart: react.ForwardRefExoticComponent<SonrChartProps & react.RefAttributes<SonrChartHandle>>;
471
+
472
+ /** Built-in chart shortcut actions surfaced to the host via `onShortcut`. */
473
+ type ShortcutAction = "escape" | "undo" | "redo" | "delete" | "copy" | "paste";
474
+ /** True when the event originates from a field where the user is typing — an
475
+ * input/textarea/select or a contenteditable element. Shortcuts must never
476
+ * hijack these (symbol search, settings inputs, etc.). */
477
+ declare function isEditableTarget(target: EventTarget | null): boolean;
478
+ /** Map a keydown to a built-in chart shortcut action, or null if none.
479
+ * Pure — reads only the event's key + modifiers, never the DOM or app state.
480
+ * The caller further gates "delete" on whether a drawing tool is armed. */
481
+ declare function resolveShortcut(e: KeyboardEvent): ShortcutAction | null;
482
+
483
+ type ScaleType = NonNullable<PriceScale["type"]>;
484
+ interface Labels {
485
+ /** Indicators menu trigger + group label. */
486
+ indicators: string;
487
+ /** Price-scale trigger prefix, shown as `${scale}: ${scaleTypes[type]}`. */
488
+ scale: string;
489
+ /** Price-scale option labels, keyed by scale type. */
490
+ scaleTypes: Record<ScaleType, string>;
491
+ /** Price-scale labels section (#41). */
492
+ priceLabelsHeading: string;
493
+ priceLabelLastValue: string;
494
+ priceLabelLastLine: string;
495
+ priceLabelHigh: string;
496
+ priceLabelLow: string;
497
+ priceLabelCountdown: string;
498
+ /** Sessions (extended-hours tint) toggle. */
499
+ sessions: string;
500
+ /** Timezone menu trigger + group label (#38). */
501
+ timezone: string;
502
+ /** Snapshot button aria-label. */
503
+ snapshot: string;
504
+ /** Settings gear aria-label + settings dialog title. */
505
+ settings: string;
506
+ /** Candle-type menu aria/title prefix. */
507
+ candleType: string;
508
+ /** Drawing-tools menu aria/title. */
509
+ drawingTools: string;
510
+ /** Magnet toggle. */
511
+ magnet: string;
512
+ undo: string;
513
+ redo: string;
514
+ /** Clear-drawings button aria-label. */
515
+ clear: string;
516
+ /** Hide/show-all-drawings toggle labels (the eye button). */
517
+ hideDrawings: string;
518
+ showDrawings: string;
519
+ /** Clear-drawings confirmation dialog: prompt, confirm button, cancel button. */
520
+ clearConfirm: string;
521
+ clearConfirmOk: string;
522
+ cancel: string;
523
+ /** Data-window / object-tree panel chrome (#45). */
524
+ dataWindow: string;
525
+ objectTree: string;
526
+ /** Shell's side-panel toggle button (indicators + objects). */
527
+ panelToggle: string;
528
+ hide: string;
529
+ show: string;
530
+ lock: string;
531
+ unlock: string;
532
+ remove: string;
533
+ close: string;
534
+ noIndicators: string;
535
+ noDrawings: string;
536
+ /** Object-tree per-drawing actions (#35). */
537
+ duplicate: string;
538
+ bringToFront: string;
539
+ sendToBack: string;
540
+ searchUnavailable: string;
541
+ searching: string;
542
+ noResults: string;
543
+ /** Save / Load dialog (#45). */
544
+ saveLoad: string;
545
+ saveLoadExportLabel: string;
546
+ saveLoadImportLabel: string;
547
+ saveLoadCopy: string;
548
+ saveLoadCopied: string;
549
+ saveLoadDownload: string;
550
+ saveLoadLoad: string;
551
+ saveLoadError: string;
552
+ saveLoadClose: string;
553
+ /** Go-to-date dialog (#45). */
554
+ goToDate: string;
555
+ goToDateGo: string;
556
+ /** Symbol-info dialog (#45). */
557
+ symbolInfo: string;
558
+ symbolInfoTicker: string;
559
+ symbolInfoName: string;
560
+ symbolInfoPricePrecision: string;
561
+ symbolInfoVolumePrecision: string;
562
+ symbolInfoUnknown: string;
563
+ symbolInfoLoading: string;
564
+ symbolInfoType: string;
565
+ symbolInfoPointValue: string;
566
+ symbolInfoListedExchange: string;
567
+ symbolInfoExchange: string;
568
+ symbolInfoTickSize: string;
569
+ symbolInfoSession: string;
570
+ /** Symbol-info metadata fields (#39). */
571
+ symbolInfoCurrency: string;
572
+ symbolInfoUnit: string;
573
+ symbolInfoDescription: string;
574
+ symbolInfoPriceSource: string;
575
+ /** Nav / control bar (#45). */
576
+ navControls: string;
577
+ zoomOut: string;
578
+ zoomIn: string;
579
+ fitContent: string;
580
+ goToRealtime: string;
581
+ /** Market-status badge (#45). */
582
+ marketPre: string;
583
+ marketOpen: string;
584
+ marketAfter: string;
585
+ marketClosed: string;
586
+ marketTimezone: string;
587
+ /** Settings dialog section (nav) titles. */
588
+ settingsSections: Record<"candles" | "indicators" | "grid" | "sessions" | "drawing" | "drawings", string>;
589
+ /** Optional per-style overrides for the candle menu; falls back to the
590
+ * option's own `label` when a style is not listed. */
591
+ candleStyles: Partial<Record<CandleStyle, string>>;
592
+ /** Optional per-tool overrides for the drawing menu; falls back to the
593
+ * tool option's own `label` when a tool is not listed. */
594
+ drawingToolLabels: Partial<Record<DrawingTool, string>>;
595
+ }
596
+ declare const DEFAULT_LABELS: Labels;
597
+ /** Merge a partial label override over the English defaults (nested records
598
+ * merged one level deep). Returns DEFAULT_LABELS unchanged when nothing is
599
+ * passed, so the no-`labels` path allocates nothing. */
600
+ declare function mergeLabels(over?: Partial<Labels>): Labels;
601
+
602
+ /** Common KLineChart indicators offered by default. `pane` decides overlay vs
603
+ * sub-pane. Override via the `options` prop. */
604
+ interface IndicatorOption {
605
+ name: string;
606
+ label: string;
607
+ pane?: "main" | "new";
608
+ }
609
+ declare const DEFAULT_INDICATOR_OPTIONS: IndicatorOption[];
610
+ declare function IndicatorMenu({ chartRef, options, className, labels, }: {
611
+ chartRef: RefObject<SonrChartHandle>;
612
+ options?: IndicatorOption[];
613
+ className?: string;
614
+ labels?: Partial<Labels>;
615
+ }): react.JSX.Element;
616
+
617
+ interface DrawingToolOption {
618
+ tool: DrawingTool;
619
+ label: string;
620
+ }
621
+ declare const DEFAULT_DRAWING_TOOLS: DrawingToolOption[];
622
+ declare const EXTENDED_DRAWING_TOOLS: DrawingToolOption[];
623
+ declare const USER_DRAWING_GROUP = "sonr-user-drawing";
624
+ /** Human label for a placed drawing in the object tree. Text labels show their
625
+ * own content; freehand shares one overlay name; everything else maps to its
626
+ * tool label (falling back to the raw overlay name). Pure. */
627
+ declare function drawingLabel(name: string, extendData?: unknown): string;
628
+
629
+ declare function DrawingToolbar({ chartRef, tools, className, showClear, showHide, showMagnet, showHistory, labels, }: {
630
+ chartRef: RefObject<SonrChartHandle>;
631
+ tools?: DrawingToolOption[];
632
+ className?: string;
633
+ showClear?: boolean;
634
+ /** Show the hide/show-all-drawings eye toggle. Default true. */
635
+ showHide?: boolean;
636
+ showMagnet?: boolean;
637
+ showHistory?: boolean;
638
+ labels?: Partial<Labels>;
639
+ }): react.JSX.Element;
640
+
641
+ declare function ConfirmDialog({ open, message, confirmLabel, cancelLabel, onConfirm, onCancel, }: {
642
+ open: boolean;
643
+ message: string;
644
+ confirmLabel?: string;
645
+ cancelLabel?: string;
646
+ onConfirm: () => void;
647
+ onCancel: () => void;
648
+ }): react.ReactPortal | null;
649
+
650
+ declare function DataWindow({ chartRef, className, labels, }: {
651
+ chartRef: RefObject<SonrChartHandle>;
652
+ className?: string;
653
+ labels?: Partial<Labels>;
654
+ }): react.JSX.Element;
655
+
656
+ declare function ObjectTree({ chartRef, className, labels, }: {
657
+ chartRef: RefObject<SonrChartHandle>;
658
+ className?: string;
659
+ labels?: Partial<Labels>;
660
+ }): react.JSX.Element;
661
+
662
+ /** One lookback button: a label, the window length in ms (Infinity = all data),
663
+ * and the words used in the "{range} in {interval} intervals" tooltip. */
664
+ interface RangeOption {
665
+ label: string;
666
+ ms: number;
667
+ title: string;
668
+ }
669
+ declare const DEFAULT_RANGES: RangeOption[];
670
+ declare function TimeframeBar({ chartRef, interval, ranges, className, children, }: {
671
+ chartRef: RefObject<SonrChartHandle>;
672
+ /** Current resolution — only used to render the tooltip. */
673
+ interval: Interval;
674
+ /** Lookback ranges to offer, in display order (defaults to DEFAULT_RANGES). */
675
+ ranges?: RangeOption[];
676
+ className?: string;
677
+ /** Optional right-aligned slot for host nav/control widgets. */
678
+ children?: ReactNode;
679
+ }): react.JSX.Element;
680
+
681
+ /** One selectable timezone: an IANA name plus a short display label. */
682
+ interface TimezoneOption {
683
+ /** IANA timezone name, e.g. "America/New_York". Passed to chart.setTimezone. */
684
+ value: string;
685
+ /** Short display label, e.g. "New York". */
686
+ label: string;
687
+ }
688
+ /** The chart's default timezone — US equities exchange time (ET). */
689
+ declare const DEFAULT_TIMEZONE = "America/New_York";
690
+ /** Curated common trading timezones, roughly west→east. Hosts can pass their own
691
+ * set to <TimezoneMenu> or extend this via getTimezoneApi(). */
692
+ declare const DEFAULT_TIMEZONES: TimezoneOption[];
693
+ /** Human label for an IANA timezone, falling back to the raw name (with the
694
+ * "Area/City" prefix stripped and underscores spaced) when it isn't in the
695
+ * curated set. Pure. */
696
+ declare function timezoneLabel(tz: string, options?: TimezoneOption[]): string;
697
+ /**
698
+ * Timezone API (issue #38 `getTimezoneApi`). Returns the curated timezone list
699
+ * and a resolver, letting a host discover the built-in options and label an
700
+ * arbitrary IANA zone. Accepts custom aliases (merged ahead of the defaults) so
701
+ * a host can surface its own named zones.
702
+ */
703
+ declare function getTimezoneApi(customAliases?: TimezoneOption[]): {
704
+ timezones: TimezoneOption[];
705
+ label: (tz: string) => string;
706
+ };
707
+
708
+ declare function TimezoneMenu({ chartRef, options, className, labels, }: {
709
+ chartRef: RefObject<SonrChartHandle>;
710
+ /** Timezones to offer (defaults to the curated common set). */
711
+ options?: TimezoneOption[];
712
+ className?: string;
713
+ labels?: Partial<Labels>;
714
+ }): react.JSX.Element;
715
+
716
+ /** Milliseconds in one unit of each period type. Week/month/year are nominal
717
+ * (calendar-agnostic) — used only for the bar-close countdown, where an exact
718
+ * calendar length isn't needed. */
719
+ declare const UNIT_MS: Record<PeriodType, number>;
720
+ /**
721
+ * Parse a resolution token to a KLineChart Period.
722
+ *
723
+ * Rules (case-insensitive):
724
+ * - `<n>S` → seconds (e.g. "10S", "30S", "5S")
725
+ * - `<n>H` → hours; bare `"60"` also maps to 1 hour (back-compat with the
726
+ * original interval set, where "60" meant hourly)
727
+ * - `D` / `<n>D` → days
728
+ * - `W` / `<n>W` → weeks
729
+ * - `MO` / `<n>MO` → months
730
+ * - `Y` / `<n>Y` → years
731
+ * - `<n>` → minutes (e.g. "1", "5", "15", "240")
732
+ * - anything unrecognized → 1 minute (safe default)
733
+ */
734
+ declare function parseResolution(interval: Interval): {
735
+ type: PeriodType;
736
+ span: number;
737
+ };
738
+ /** Duration of one bar at this resolution, in ms (drives the bar-close
739
+ * countdown). Nominal for week/month/year (see UNIT_MS). */
740
+ declare function resolutionMs(interval: Interval): number;
741
+ /** Human words for a resolution, e.g. "30 minute", "1 hour" — used in tooltips
742
+ * and menus. Pure. */
743
+ declare function resolutionLabel(interval: Interval): string;
744
+ /** A resolution option for a resolution menu/toolbar. */
745
+ interface ResolutionOption {
746
+ /** The token passed as `interval`. */
747
+ value: Interval;
748
+ /** Short display label (e.g. "5m", "1H", "D"). */
749
+ label: string;
750
+ }
751
+ /** A sensible default resolution set spanning seconds → months. Hosts can pass
752
+ * their own; any custom token `parseResolution` understands is valid. */
753
+ declare const DEFAULT_RESOLUTIONS: ResolutionOption[];
754
+
755
+ /** Quote metadata attached to a symbol (subset of SymbolInfo). */
756
+ interface QuoteFormat {
757
+ /** Currency code or sign, prefixed (e.g. "USD", "$"). */
758
+ currency?: string;
759
+ /** Unit, suffixed (e.g. "pts", "¢"). */
760
+ unit?: string;
761
+ }
762
+ /**
763
+ * Decorate an already-formatted price string with a currency prefix and/or unit
764
+ * suffix. A glyph currency ("$", "€") hugs the number; an alphabetic code
765
+ * ("USD") gets a space. Passing neither returns the text unchanged, so this
766
+ * is a no-op for symbols without quote metadata. Pure.
767
+ */
768
+ declare function formatWithUnit(text: string, quote?: QuoteFormat): string;
769
+
770
+ type BrandCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right";
771
+ interface BrandMarkProps {
772
+ /** Image source for a logo, rendered as an <img> (sized by `height`). */
773
+ src?: string;
774
+ alt?: string;
775
+ /** Brand content when not using `src` — a wordmark, inline SVG, etc. */
776
+ children?: ReactNode;
777
+ /** Corner placement within the positioned parent. Default "bottom-left". */
778
+ position?: BrandCorner;
779
+ /** Mark opacity (kept subtle by default). */
780
+ opacity?: number;
781
+ /** Optional link — wraps the mark in an anchor (opens in a new tab) and
782
+ * re-enables pointer events for it. */
783
+ href?: string;
784
+ /** Logo image height in px (only when `src` is set). Default 18. */
785
+ height?: number;
786
+ className?: string;
787
+ }
788
+ declare function BrandMark({ src, alt, children, position, opacity, href, height, className }: BrandMarkProps): react.JSX.Element;
789
+
790
+ interface SonrChartShellProps {
791
+ symbol: string;
792
+ interval: Interval;
793
+ dataSource: DataSource;
794
+ theme?: Theme | string;
795
+ /** Resolution buttons in the toolbar. Defaults to 10S…D. */
796
+ intervals?: Interval[];
797
+ /** Lookback ranges for the bottom bar. */
798
+ ranges?: RangeOption[];
799
+ /** Data-source label shown in the header (e.g. "Alpaca"). */
800
+ source?: string;
801
+ /** Instrument venue label for the Symbol-info dialog (e.g. "Alpaca"). */
802
+ exchange?: string;
803
+ onIntervalChange?: (interval: Interval) => void;
804
+ onSymbolChange?: (symbol: string) => void;
805
+ /** Brand mark content (host logo), shown in a chart corner. Omit for none. */
806
+ brand?: ReactNode;
807
+ brandCorner?: BrandCorner;
808
+ brandOpacity?: number;
809
+ /** Snapshot filename. Defaults to `${symbol}-${interval}.png`. */
810
+ snapshotName?: string;
811
+ indicators?: (string | IndicatorSpec)[];
812
+ sessions?: SessionTint;
813
+ watermark?: boolean | Partial<WatermarkOptions>;
814
+ patterns?: PatternMarker[];
815
+ priceLines?: PriceLine[];
816
+ orderLines?: OrderLine[];
817
+ timezone?: string;
818
+ /** Localized chrome strings, threaded to every piece. */
819
+ labels?: Partial<Labels>;
820
+ className?: string;
821
+ style?: CSSProperties;
822
+ }
823
+ /**
824
+ * The full chart application shell. Forwards a ref to the underlying
825
+ * SonrChartHandle so a host can still drive the chart imperatively.
826
+ */
827
+ declare const SonrChartShell: react.ForwardRefExoticComponent<SonrChartShellProps & react.RefAttributes<SonrChartHandle>>;
828
+
829
+ declare function isChartState(value: unknown): value is ChartState;
830
+ declare function SaveLoadDialog({ chartRef, open, onClose, labels, }: {
831
+ chartRef: RefObject<SonrChartHandle>;
832
+ open: boolean;
833
+ onClose: () => void;
834
+ labels?: Partial<Labels>;
835
+ }): react.ReactPortal | null;
836
+
837
+ declare function parseLocalDateTime(value: string): number | null;
838
+ declare function GoToDateDialog({ chartRef, open, onClose, labels, }: {
839
+ chartRef: RefObject<SonrChartHandle>;
840
+ open: boolean;
841
+ onClose: () => void;
842
+ labels?: Partial<Labels>;
843
+ }): react.ReactPortal | null;
844
+
845
+ declare function SymbolInfoDialog({ dataSource, symbol, open, onClose, labels, type, exchange, listedExchange, pointValue, tickSize, now, }: {
846
+ dataSource: DataSource;
847
+ symbol: string;
848
+ open: boolean;
849
+ onClose: () => void;
850
+ labels?: Partial<Labels>;
851
+ /** Instrument type (default "Stock"). */
852
+ type?: string;
853
+ /** Trading venue label (e.g. "Alpaca"). */
854
+ exchange?: string;
855
+ /** Primary listing exchange, if known (default "—"). */
856
+ listedExchange?: string;
857
+ /** Contract point value (default 1 for cash equities). */
858
+ pointValue?: number;
859
+ /** Minimum price increment. Defaults to 10^-pricePrecision from resolveSymbol. */
860
+ tickSize?: number;
861
+ /** Fixed instant for the session timeline (defaults to the live clock). */
862
+ now?: number;
863
+ }): react.ReactPortal | null;
864
+
865
+ declare function NavControlBar({ chartRef, labels, className, }: {
866
+ chartRef: RefObject<SonrChartHandle>;
867
+ labels?: Partial<Labels>;
868
+ className?: string;
869
+ }): react.JSX.Element;
870
+
871
+ /** The four US-equities session phases. */
872
+ type MarketPhase = "pre" | "open" | "after" | "closed";
873
+ /**
874
+ * Classify an instant into a US-equities session phase, evaluated in ET.
875
+ * Weekends are "closed"; holidays are not modeled. Pure.
876
+ */
877
+ declare function marketStatus(nowMs: number): MarketPhase;
878
+ interface MarketStatusProps {
879
+ /** Fixed instant (epoch ms) to classify. Omit to track the live clock (the
880
+ * badge re-evaluates every 30s). */
881
+ now?: number;
882
+ labels?: Partial<Labels>;
883
+ className?: string;
884
+ }
885
+ /**
886
+ * Market-status pill (colored dot + phase). Click it to open a popover with a
887
+ * countdown to the next session transition, a day timeline, and the exchange
888
+ * timezone. Uncontrolled clock by default; pass `now` to pin a fixed instant.
889
+ */
890
+ declare function MarketStatus({ now, labels, className }: MarketStatusProps): react.JSX.Element;
891
+
892
+ interface ChartHeaderProps {
893
+ chartRef: RefObject<SonrChartHandle>;
894
+ symbol: string;
895
+ interval: Interval;
896
+ /** Data-source label shown after `symbol · interval` (e.g. "Alpaca"). */
897
+ source?: string;
898
+ /** Precision for O/H/L/C/change (defaults to 2). */
899
+ pricePrecision?: number;
900
+ labels?: Partial<Labels>;
901
+ className?: string;
902
+ }
903
+ declare function ChartHeader({ chartRef, symbol, interval, source, pricePrecision, labels, className }: ChartHeaderProps): react.JSX.Element;
904
+
905
+ interface CandleStyleOption {
906
+ style: CandleStyle;
907
+ label: string;
908
+ }
909
+ declare const DEFAULT_CANDLE_STYLES: CandleStyleOption[];
910
+ declare function CandleMenu({ value, onChange, options, className, labels, }: {
911
+ value?: CandleStyle;
912
+ onChange?: (style: CandleStyle) => void;
913
+ options?: CandleStyleOption[];
914
+ className?: string;
915
+ labels?: Partial<Labels>;
916
+ }): react.JSX.Element;
917
+
918
+ declare function PriceScaleMenu({ value, onChange, className, labels, chartRef, }: {
919
+ value?: PriceScale;
920
+ onChange?: (scale: PriceScale) => void;
921
+ className?: string;
922
+ labels?: Partial<Labels>;
923
+ /** When supplied, renders the price-scale label toggles (#41). */
924
+ chartRef?: RefObject<SonrChartHandle>;
925
+ }): react.JSX.Element;
926
+
927
+ declare function SettingsModal({ chartRef, open, onClose, labels, }: {
928
+ chartRef: RefObject<SonrChartHandle>;
929
+ open: boolean;
930
+ onClose: () => void;
931
+ labels?: Partial<Labels>;
932
+ }): react.ReactPortal | null;
933
+
934
+ declare function ChartToolbar({ chartRef, intervals, interval, onIntervalChange, candleStyle, onCandleStyleChange, candleStyles, priceScale, onPriceScaleChange, sessions, onSessionsChange, indicatorOptions, drawingTools, showCandle, showScale, showSessions, showDrawing, showSnapshot, showSettings, snapshotName, dataSource, onSymbolSelect, spreadOperators, className, labels, children, }: {
935
+ chartRef: RefObject<SonrChartHandle>;
936
+ intervals?: Interval[];
937
+ interval?: Interval;
938
+ onIntervalChange?: (interval: Interval) => void;
939
+ candleStyle?: CandleStyle;
940
+ onCandleStyleChange?: (style: CandleStyle) => void;
941
+ candleStyles?: CandleStyleOption[];
942
+ priceScale?: PriceScale;
943
+ onPriceScaleChange?: (scale: PriceScale) => void;
944
+ sessions?: boolean;
945
+ onSessionsChange?: (on: boolean) => void;
946
+ indicatorOptions?: IndicatorOption[];
947
+ drawingTools?: DrawingToolOption[];
948
+ showCandle?: boolean;
949
+ showScale?: boolean;
950
+ showSessions?: boolean;
951
+ showDrawing?: boolean;
952
+ showSnapshot?: boolean;
953
+ showSettings?: boolean;
954
+ snapshotName?: string;
955
+ /** DataSource used to power the optional symbol-search box (issue #37). */
956
+ dataSource?: DataSource;
957
+ /** When provided (with `dataSource`), a SymbolSearch renders at the toolbar's
958
+ * left; picking a result fires this. Omit for the pre-#37 toolbar. */
959
+ onSymbolSelect?: (symbol: string) => void;
960
+ /** Forwarded to SymbolSearch — allow spread/expression pass-through. */
961
+ spreadOperators?: boolean;
962
+ className?: string;
963
+ /** Localized chrome strings (issue #46). Merged over English defaults and
964
+ * threaded to the menus/settings; omit for the current English. */
965
+ labels?: Partial<Labels>;
966
+ children?: ReactNode;
967
+ }): react.JSX.Element;
968
+
969
+ declare function SymbolSearch({ dataSource, onSelect, spreadOperators, placeholder, className, }: {
970
+ dataSource: DataSource;
971
+ onSelect: (symbol: string) => void;
972
+ spreadOperators?: boolean;
973
+ placeholder?: string;
974
+ className?: string;
975
+ }): react.JSX.Element;
976
+
977
+ declare function ToolbarButton({ active, children, className, ...rest }: {
978
+ active?: boolean;
979
+ children: ReactNode;
980
+ } & ButtonHTMLAttributes<HTMLButtonElement>): react.JSX.Element;
981
+
982
+ /** Inject the default toolbar stylesheet once. No-op on the server, when already
983
+ * injected, or if the host opted out via `data-sonr-no-default-styles` on
984
+ * <html> (for consumers that ship a full theme and want nothing shipped). */
985
+ declare function ensureDefaultStyles(): void;
986
+
987
+ declare const SONR_TRADE_BOX = "sonrTradeBox";
988
+ interface TradeBoxData {
989
+ up?: boolean;
990
+ label?: string;
991
+ /** Draw a horizontal reference line at the entry price across the box. */
992
+ entryLine?: boolean;
993
+ }
994
+ type Params = OverlayCreateFiguresCallbackParams<TradeBoxData>;
995
+ declare function tradeBoxFigures({ coordinates, overlay }: Params): OverlayFigure[];
996
+ /** Register the trade-review overlay once. Idempotent. */
997
+ declare function registerTradeReview(): void;
998
+
999
+ /** All extended overlay names, in toolbar order. */
1000
+ declare const EXTENDED_OVERLAYS: readonly ["horizontalRay", "crossLine", "arrow", "fibExtension", "fibTimeZone", "dateRange", "datePriceRange"];
1001
+ /** Trend-based Fibonacci extension levels (retracement + projection). */
1002
+ declare const FIB_EXTENSION_LEVELS: readonly number[];
1003
+ /** Fibonacci sequence multipliers for time zones (starts 1,2,3,5,8,…). Pure. */
1004
+ declare function fibSequence(count: number): number[];
1005
+ /**
1006
+ * Arrowhead polygon for a segment ending at (x2,y2), coming from (x1,y1). Two
1007
+ * barbs swept back from the tip by `size` px at ±`spread` radians. Pure. Returns
1008
+ * [leftBarb, tip, rightBarb]. Zero-length segments yield a degenerate triangle
1009
+ * at the tip (harmless).
1010
+ */
1011
+ declare function arrowHeadPoints(x1: number, y1: number, x2: number, y2: number, size?: number, spread?: number): Coordinate[];
1012
+ /** Human duration for a millisecond span, coarse-grained (largest two units).
1013
+ * Pure. E.g. 3_660_000 → "1h 1m", 45_000 → "45s". */
1014
+ declare function humanDuration(ms: number): string;
1015
+ /** Measurement label for a date range: bar count + human time span. Pure. */
1016
+ declare function dateRangeLabel(bars: number, ms: number): string;
1017
+ /** Register all extended-family overlays once. Idempotent. */
1018
+ declare function registerExtendedDrawings(): void;
1019
+
1020
+ declare function downloadSnapshot(handle: SonrChartHandle | null, filename?: string, opts?: {
1021
+ type?: "png" | "jpeg";
1022
+ background?: string;
1023
+ includeOverlays?: boolean;
1024
+ }): boolean;
1025
+
1026
+ declare function toHeikinAshi(bars: Bar[]): Bar[];
1027
+
1028
+ declare const SHAPE_RECTANGLE = "rectangle";
1029
+ declare const SHAPE_ELLIPSE = "ellipse";
1030
+ declare const SHAPE_TRIANGLE = "triangle";
1031
+ declare const SHAPE_PRICE_RANGE = "priceRange";
1032
+ declare const SHAPE_RISK_REWARD = "riskReward";
1033
+ /** All shape/measurement overlay names, in toolbar order. */
1034
+ declare const SHAPE_OVERLAYS: readonly ["rectangle", "ellipse", "triangle", "priceRange", "riskReward"];
1035
+ /** Format a price-range measurement: absolute delta + percentage between two
1036
+ * prices. Pure so it's unit-testable. */
1037
+ declare function priceRangeLabel(from: number, to: number): string;
1038
+ /** Risk/reward stats for a long setup (entry / stop / target). Pure so it's
1039
+ * unit-testable. `rr` is reward-per-unit-risk (an R multiple); NaN-safe. */
1040
+ declare function riskRewardStats(entry: number, stop: number, target: number): {
1041
+ risk: number;
1042
+ reward: number;
1043
+ rr: number;
1044
+ };
1045
+ /** Register all shape/measurement overlays once. Idempotent. */
1046
+ declare function registerShapeOverlays(): void;
1047
+
1048
+ /** Register a named theme's style object so `theme="<name>"` applies it. */
1049
+ declare function registerTheme(name: string, styles: DeepPartial<Styles>): void;
1050
+ /** Look up a previously registered theme's styles (undefined if unknown). */
1051
+ declare function getRegisteredTheme(name: string): DeepPartial<Styles> | undefined;
1052
+ /**
1053
+ * KLineChart style object for a theme. Deliberately limited to the style keys
1054
+ * that typecheck cleanly under klinecharts v10 (grid, candle bars, axes,
1055
+ * crosshair line) — callers can override anything via the `styles` prop.
1056
+ */
1057
+ declare function themeStyles(theme: Theme): DeepPartial<Styles>;
1058
+ declare const PALETTE: {
1059
+ GREEN: string;
1060
+ RED: string;
1061
+ DARK: {
1062
+ text: string;
1063
+ muted: string;
1064
+ grid: string;
1065
+ axis: string;
1066
+ pill: string;
1067
+ pillText: string;
1068
+ };
1069
+ LIGHT: {
1070
+ text: string;
1071
+ muted: string;
1072
+ grid: string;
1073
+ axis: string;
1074
+ pill: string;
1075
+ pillText: string;
1076
+ };
1077
+ };
1078
+ /**
1079
+ * Resolve a theme selector to a KLineChart style object (issue #46).
1080
+ * "dark"/"light" use the built-ins unchanged. Any other string is looked up in
1081
+ * `customThemes` first, then the module registry; a match layers over the dark
1082
+ * base so partial palettes still get sensible crosshair/candle defaults. An
1083
+ * unknown name falls back to the dark theme.
1084
+ */
1085
+ declare function resolveThemeStyles(theme: Theme | string, customThemes?: Record<string, DeepPartial<Styles>>): DeepPartial<Styles>;
1086
+
1087
+ /**
1088
+ * Read a CSS custom property's computed value. Returns "" when the variable is
1089
+ * unset or when there is no `document` (SSR). `name` may include or omit `--`.
1090
+ */
1091
+ declare function getCSSCustomProperty(name: string, el?: Element | null): string;
1092
+ /**
1093
+ * Write a CSS custom property (inline `style`). No-op under SSR. `name` may
1094
+ * include or omit `--`. Defaults to `:root` (document.documentElement).
1095
+ */
1096
+ declare function setCSSCustomProperty(name: string, value: string, el?: HTMLElement | null): void;
1097
+
1098
+ declare const SESSION_INDICATOR = "SONR_SESSION";
1099
+ declare const PATTERN_INDICATOR = "SONR_PATTERNS";
1100
+ declare const WATERMARK_INDICATOR = "SONR_WATERMARK";
1101
+ declare const SERIES_INDICATOR = "SONR_SERIES";
1102
+ declare const VWAP_INDICATOR = "VWAP";
1103
+ /** Background watermark content (the underlaid ticker + interval). */
1104
+ interface WatermarkData {
1105
+ title: string;
1106
+ subtitle?: string;
1107
+ color: string;
1108
+ }
1109
+ interface SessionColors {
1110
+ premarket: string;
1111
+ afterhours: string;
1112
+ }
1113
+ declare const DEFAULT_SESSION_COLORS: SessionColors;
1114
+ declare function registerSonrIndicators(): void;
1115
+
1116
+ export { BRUSH_OVERLAY, type Bar, type BrandCorner, BrandMark, type BrandMarkProps, type BrushStyle, type BrushTool, CandleMenu, type CandleStyle, type CandleStyleOption, ChartHeader, type ChartHeaderProps, type ChartState, ChartToolbar, type CompareSpec, ConfirmDialog, DEFAULT_CANDLE_STYLES, DEFAULT_DRAWING_TOOLS, DEFAULT_INDICATOR_OPTIONS, DEFAULT_LABELS, DEFAULT_RANGES, DEFAULT_RESOLUTIONS, DEFAULT_SESSION_COLORS, DEFAULT_TIMEZONE, DEFAULT_TIMEZONES, type DataSource, DataWindow, type DrawingRow, type DrawingSnapshot, type DrawingSnapshotItem, DrawingTemplateStore, type DrawingTool, type DrawingToolOption, DrawingToolbar, EXTENDED_DRAWING_TOOLS, EXTENDED_OVERLAYS, FIB_EXTENSION_LEVELS, GoToDateDialog, IndicatorMenu, type IndicatorOption, type IndicatorRow, type IndicatorSpec, type Interval, type Labels, type Magnet, type MarketPhase, MarketStatus, type MarketStatusProps, NavControlBar, ObjectTree, type OrderLine, PALETTE, PATTERN_INDICATOR, type PatternMarker, type PriceLabels, type PriceLine, type PriceScale, PriceScaleMenu, type QuoteFormat, type RangeOption, type ResolutionOption, SERIES_INDICATOR, SESSION_INDICATOR, SHAPE_ELLIPSE, SHAPE_OVERLAYS, SHAPE_PRICE_RANGE, SHAPE_RECTANGLE, SHAPE_RISK_REWARD, SHAPE_TRIANGLE, SONR_TRADE_BOX, SaveLoadDialog, type SessionTint, SettingsModal, type ShortcutAction, SonrChart, type SonrChartHandle, type SonrChartProps, SonrChartShell, type SonrChartShellProps, type SymbolInfo, SymbolInfoDialog, SymbolSearch, type SymbolSearchResult, TEXT_OVERLAY, type TextData, type Theme, TimeframeBar, TimezoneMenu, type TimezoneOption, ToolbarButton, UNIT_MS, USER_DRAWING_GROUP, VWAP_INDICATOR, WATERMARK_INDICATOR, type WatermarkData, type WatermarkOptions, arrowHeadPoints, dateRangeLabel, downloadSnapshot, drawingLabel, ensureDefaultStyles, fibSequence, formatWithUnit, getCSSCustomProperty, getRegisteredTheme, getTimezoneApi, humanDuration, isChartState, isEditableTarget, marketStatus, mergeLabels, parseLocalDateTime, parseResolution, priceRangeLabel, registerExtendedDrawings, registerShapeOverlays, registerSonrIndicators, registerTextOverlay, registerTheme, registerTradeReview, resolutionLabel, resolutionMs, resolveShortcut, resolveThemeStyles, riskRewardStats, setCSSCustomProperty, themeStyles, timezoneLabel, toHeikinAshi, tradeBoxFigures };