@luxalgo/vela 0.7.8 → 0.8.1
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/NOTICE +28 -28
- package/README.md +15 -7
- package/dist/{DataProvider-CGa4KHRa.d.cts → DataProvider-BrlxntPN.d.cts} +1 -1
- package/dist/{DataProvider-CmWUtDVL.d.ts → DataProvider-DwFIoV4r.d.ts} +1 -1
- package/dist/{chunk-N4ZZYLMP.js → chunk-ATGTCWHJ.js} +726 -273
- package/dist/{chunk-CAFCLMPF.js → chunk-BZQM2XO7.js} +1 -0
- package/dist/{chunk-M6GP7DAX.js → chunk-DBDXKZUF.js} +474 -47
- package/dist/{chunk-BFA32GOU.js → chunk-EZ5FWVLA.js} +5 -2
- package/dist/{chunk-PVGWNF7V.js → chunk-LMBYEGUR.js} +2 -2
- package/dist/{chunk-WTWGEB7K.js → chunk-NELQJCGK.js} +298 -5
- package/dist/{contributions-DF_Ea07m.d.cts → contributions-CtlptxR8.d.cts} +187 -5
- package/dist/{contributions-nKOSeLy8.d.ts → contributions-tjNExo1o.d.ts} +187 -5
- package/dist/index.cjs +1044 -272
- package/dist/index.d.cts +24 -8
- package/dist/index.d.ts +24 -8
- package/dist/index.js +28 -4
- package/dist/{options-D1AJKsn_.d.ts → options-BnEPUuVV.d.cts} +1 -1
- package/dist/{options-D1AJKsn_.d.cts → options-BnEPUuVV.d.ts} +1 -1
- package/dist/{plugin-6F04gjQe.d.cts → plugin-BWxJRKzS.d.cts} +10 -4
- package/dist/{plugin-BLsNipkc.d.ts → plugin-e2WUEtiI.d.ts} +10 -4
- package/dist/plugin.cjs +1 -0
- package/dist/plugin.d.cts +4 -4
- package/dist/plugin.d.ts +4 -4
- package/dist/plugin.js +2 -2
- package/dist/providers/binance.d.cts +2 -2
- package/dist/providers/binance.d.ts +2 -2
- package/dist/providers/coinbase.d.cts +2 -2
- package/dist/providers/coinbase.d.ts +2 -2
- package/dist/providers/hyperliquid.d.cts +2 -2
- package/dist/providers/hyperliquid.d.ts +2 -2
- package/dist/{statusline-model-DAFyqVmR.d.ts → statusline-model-DFY7tuHj.d.cts} +5 -3
- package/dist/{statusline-model-BoWJ3cWQ.d.cts → statusline-model-zKXtGIjj.d.ts} +5 -3
- package/dist/ui.cjs +301 -3
- package/dist/ui.d.cts +75 -2
- package/dist/ui.d.ts +75 -2
- package/dist/ui.js +3 -3
- package/dist/vela.global.js +1046 -274
- package/dist/vela.global.min.js +82 -87
- package/dist/widget.cjs +1504 -327
- package/dist/widget.d.cts +26 -7
- package/dist/widget.d.ts +26 -7
- package/dist/widget.js +7 -7
- package/dist/workspace.cjs +1507 -327
- package/dist/workspace.d.cts +125 -7
- package/dist/workspace.d.ts +125 -7
- package/dist/workspace.js +6 -6
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { svg24, NEUTRAL, BEARISH, WARNING, BULLISH, INFO, ACCENT_BRIGHT, VALID, INVALID, MARKER, ACCENT, injectStyles, iconEl } from './chunk-
|
|
1
|
+
import { svg24, NEUTRAL, BEARISH, WARNING, BULLISH, INFO, ACCENT_BRIGHT, VALID, INVALID, MARKER, ACCENT, injectStyles, iconEl } from './chunk-BZQM2XO7.js';
|
|
2
2
|
|
|
3
3
|
// src/core/model/series.ts
|
|
4
4
|
function isLineLikeSeries(spec) {
|
|
@@ -5952,6 +5952,9 @@ function pinnedTopbarActionIds(comp) {
|
|
|
5952
5952
|
}
|
|
5953
5953
|
|
|
5954
5954
|
// src/widget/contributions.ts
|
|
5955
|
+
function mobilePlacement(action) {
|
|
5956
|
+
return action.mobile ?? (action.align === "left" ? "bar" : "menu");
|
|
5957
|
+
}
|
|
5955
5958
|
var registry3 = /* @__PURE__ */ new Map();
|
|
5956
5959
|
var attachments = /* @__PURE__ */ new Map();
|
|
5957
5960
|
var panels = /* @__PURE__ */ new Map();
|
|
@@ -6393,4 +6396,4 @@ var SidePanel = class {
|
|
|
6393
6396
|
}
|
|
6394
6397
|
};
|
|
6395
6398
|
|
|
6396
|
-
export { AnchoredVwap, ArrowMark, Callout, CalloutBase, Comment, DEDEKIND_CURVATURE_OPTIONS, DEFAULT_DRAWING_COLOR, DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, DIRECTION_OPTIONS, DedekindTessellation, Drawing, FibRatios, FibSpiral, FixedRangeVolumeProfile, GANN_SQUARE_ARCS, GLYPH_OPTIONS, GannSquare, GlyphStamp, LINE_STYLE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, MAGNIFIER_TIMEFRAME_OPTIONS, MachFigure, Magnifier, MeasureBox, Note, OVERRIDABLE_TOPBAR_IDS, PatternDrawing, PositionTool, PriceLabel, PriceNote, RadialFib, RegressionChannel, STAMP_SIZE_OPTIONS, SegmentDrawing, SidePanel, Signpost, TEXT_SIZE_OPTIONS, TOPBAR_BUILTIN_IDS, TOPBAR_DEFAULT_LEFT, TOPBAR_DEFAULT_RIGHT, TextLabel, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, foldBaseModulation, formatDuration, getDrawingType, getNativeIndicator, inputDeltas, inputVisible, isLineLikeSeries, legendActions, legendActionsProviderFor, legendCallouts, legendCalloutsProviderFor, lineSegmentIntersection, magnifierTimeframeLabel, nativeIndicatorDescriptors, nativeIndicatorTypes, nativeInstanceChannel, normalizeSettingsRow, pinnedTopbarActionIds, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerLegendCallout, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerStatePersistence, registerSymbolRanking, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resetDrawingSettings, resolveEngines, resolveTopbarComposition, seriesInScale, seriesShownOn, settingsRowValueKeys, settingsRowVisible, sidePanels, stableSeriesId, statePersistenceHandlers, symbolRanking, tickerModifierIds, topbarActionOverride, topbarHas, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterLegendCallout, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterStatePersistence, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments };
|
|
6399
|
+
export { AnchoredVwap, ArrowMark, Callout, CalloutBase, Comment, DEDEKIND_CURVATURE_OPTIONS, DEFAULT_DRAWING_COLOR, DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, DIRECTION_OPTIONS, DedekindTessellation, Drawing, FibRatios, FibSpiral, FixedRangeVolumeProfile, GANN_SQUARE_ARCS, GLYPH_OPTIONS, GannSquare, GlyphStamp, LINE_STYLE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, MAGNIFIER_TIMEFRAME_OPTIONS, MachFigure, Magnifier, MeasureBox, Note, OVERRIDABLE_TOPBAR_IDS, PatternDrawing, PositionTool, PriceLabel, PriceNote, RadialFib, RegressionChannel, STAMP_SIZE_OPTIONS, SegmentDrawing, SidePanel, Signpost, TEXT_SIZE_OPTIONS, TOPBAR_BUILTIN_IDS, TOPBAR_DEFAULT_LEFT, TOPBAR_DEFAULT_RIGHT, TextLabel, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, foldBaseModulation, formatDuration, getDrawingType, getNativeIndicator, inputDeltas, inputVisible, isLineLikeSeries, legendActions, legendActionsProviderFor, legendCallouts, legendCalloutsProviderFor, lineSegmentIntersection, magnifierTimeframeLabel, mobilePlacement, nativeIndicatorDescriptors, nativeIndicatorTypes, nativeInstanceChannel, normalizeSettingsRow, pinnedTopbarActionIds, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerLegendCallout, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerStatePersistence, registerSymbolRanking, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resetDrawingSettings, resolveEngines, resolveTopbarComposition, seriesInScale, seriesShownOn, settingsRowValueKeys, settingsRowVisible, sidePanels, stableSeriesId, statePersistenceHandlers, symbolRanking, tickerModifierIds, topbarActionOverride, topbarHas, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterLegendCallout, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterStatePersistence, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { normalizeProps, nextUid, runMachine, spreadProps } from './chunk-
|
|
2
|
-
import { injectStyles } from './chunk-
|
|
1
|
+
import { normalizeProps, nextUid, runMachine, spreadProps } from './chunk-NELQJCGK.js';
|
|
2
|
+
import { injectStyles } from './chunk-BZQM2XO7.js';
|
|
3
3
|
import * as tooltip from '@zag-js/tooltip';
|
|
4
4
|
import * as dialog from '@zag-js/dialog';
|
|
5
5
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { overlayScrollbarCss, isDarkColor, mix, HIGHLIGHT, ACCENT_BRIGHT, ACCENT, withAlpha, injectStyles, iconAt, iconEl, BULLISH, BEARISH, WARNING, NEUTRAL } from './chunk-
|
|
1
|
+
import { overlayScrollbarCss, isDarkColor, mix, HIGHLIGHT, ACCENT_BRIGHT, ACCENT, withAlpha, injectStyles, iconAt, iconEl, BULLISH, BEARISH, WARNING, NEUTRAL } from './chunk-BZQM2XO7.js';
|
|
2
2
|
import { VanillaMachine, normalizeProps, spreadProps } from '@zag-js/vanilla';
|
|
3
3
|
export { normalizeProps, spreadProps } from '@zag-js/vanilla';
|
|
4
4
|
import * as menu from '@zag-js/menu';
|
|
@@ -1505,6 +1505,264 @@ var Dialog = class {
|
|
|
1505
1505
|
}
|
|
1506
1506
|
};
|
|
1507
1507
|
|
|
1508
|
+
// src/ui/components/date-picker/controller.ts
|
|
1509
|
+
var MONTH_LABELS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
1510
|
+
var MONTH_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
1511
|
+
var WEEKDAY_LABELS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
1512
|
+
function isoDate(d) {
|
|
1513
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
1514
|
+
}
|
|
1515
|
+
function normalizeDateInput(raw) {
|
|
1516
|
+
const m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(raw.trim());
|
|
1517
|
+
if (!m) return null;
|
|
1518
|
+
const y = Number(m[1]);
|
|
1519
|
+
const mo = Number(m[2]);
|
|
1520
|
+
const d = Number(m[3]);
|
|
1521
|
+
const dt = new Date(y, mo - 1, d);
|
|
1522
|
+
if (dt.getFullYear() !== y || dt.getMonth() !== mo - 1 || dt.getDate() !== d) return null;
|
|
1523
|
+
return isoDate(dt);
|
|
1524
|
+
}
|
|
1525
|
+
function parseIsoDate(raw) {
|
|
1526
|
+
const iso = raw ? normalizeDateInput(raw) : null;
|
|
1527
|
+
if (!iso) return null;
|
|
1528
|
+
const [y, mo, d] = iso.split("-").map(Number);
|
|
1529
|
+
return new Date(y, mo - 1, d);
|
|
1530
|
+
}
|
|
1531
|
+
function datePickerController(opts = {}) {
|
|
1532
|
+
const today = opts.today ?? /* @__PURE__ */ new Date();
|
|
1533
|
+
let selected = parseIsoDate(opts.value);
|
|
1534
|
+
let year = selected?.getFullYear() ?? today.getFullYear();
|
|
1535
|
+
let month = selected?.getMonth() ?? today.getMonth();
|
|
1536
|
+
let panel = "date";
|
|
1537
|
+
const decade = () => Math.floor(year / 10) * 10;
|
|
1538
|
+
return {
|
|
1539
|
+
get panel() {
|
|
1540
|
+
return panel;
|
|
1541
|
+
},
|
|
1542
|
+
get year() {
|
|
1543
|
+
return year;
|
|
1544
|
+
},
|
|
1545
|
+
get month() {
|
|
1546
|
+
return month;
|
|
1547
|
+
},
|
|
1548
|
+
get value() {
|
|
1549
|
+
return selected ? isoDate(selected) : null;
|
|
1550
|
+
},
|
|
1551
|
+
header() {
|
|
1552
|
+
return {
|
|
1553
|
+
month: MONTH_LABELS[month] ?? "",
|
|
1554
|
+
monthVisible: panel === "date",
|
|
1555
|
+
year: panel === "year" ? `${decade()}-${decade() + 9}` : String(year),
|
|
1556
|
+
yearDisabled: panel === "year"
|
|
1557
|
+
// in the decade panel the year reads as its title
|
|
1558
|
+
};
|
|
1559
|
+
},
|
|
1560
|
+
navLabels() {
|
|
1561
|
+
if (panel === "date") return { prev: "Previous month", next: "Next month" };
|
|
1562
|
+
if (panel === "month") return { prev: "Previous year", next: "Next year" };
|
|
1563
|
+
return { prev: "Previous decade", next: "Next decade" };
|
|
1564
|
+
},
|
|
1565
|
+
cells() {
|
|
1566
|
+
const out = [];
|
|
1567
|
+
if (panel === "date") {
|
|
1568
|
+
const startPad = new Date(year, month, 1).getDay();
|
|
1569
|
+
const days = new Date(year, month + 1, 0).getDate();
|
|
1570
|
+
const todayIso = isoDate(today);
|
|
1571
|
+
const selectedIso = selected ? isoDate(selected) : "";
|
|
1572
|
+
for (let i = 0; i < startPad; i++) out.push({ label: "", value: "", checked: false, today: false, blank: true });
|
|
1573
|
+
for (let day = 1; day <= days; day++) {
|
|
1574
|
+
const iso = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
1575
|
+
out.push({ label: String(day), value: iso, checked: iso === selectedIso, today: iso === todayIso });
|
|
1576
|
+
}
|
|
1577
|
+
return out;
|
|
1578
|
+
}
|
|
1579
|
+
if (panel === "month") {
|
|
1580
|
+
for (let m = 0; m < 12; m++) {
|
|
1581
|
+
out.push({
|
|
1582
|
+
label: MONTH_SHORT[m] ?? "",
|
|
1583
|
+
value: m,
|
|
1584
|
+
checked: selected?.getFullYear() === year && selected.getMonth() === m,
|
|
1585
|
+
today: today.getFullYear() === year && today.getMonth() === m
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
return out;
|
|
1589
|
+
}
|
|
1590
|
+
const d = decade();
|
|
1591
|
+
for (let y = d - 1; y <= d + 10; y++) {
|
|
1592
|
+
out.push({ label: String(y), value: y, checked: selected?.getFullYear() === y, today: today.getFullYear() === y, outside: y < d || y > d + 9 });
|
|
1593
|
+
}
|
|
1594
|
+
return out;
|
|
1595
|
+
},
|
|
1596
|
+
step(dir) {
|
|
1597
|
+
if (panel === "date") {
|
|
1598
|
+
month += dir;
|
|
1599
|
+
if (month < 0) {
|
|
1600
|
+
month = 11;
|
|
1601
|
+
year -= 1;
|
|
1602
|
+
}
|
|
1603
|
+
if (month > 11) {
|
|
1604
|
+
month = 0;
|
|
1605
|
+
year += 1;
|
|
1606
|
+
}
|
|
1607
|
+
} else {
|
|
1608
|
+
year += panel === "month" ? dir : dir * 10;
|
|
1609
|
+
}
|
|
1610
|
+
},
|
|
1611
|
+
showMonths() {
|
|
1612
|
+
panel = "month";
|
|
1613
|
+
},
|
|
1614
|
+
showYears() {
|
|
1615
|
+
panel = "year";
|
|
1616
|
+
},
|
|
1617
|
+
choose(cell) {
|
|
1618
|
+
if (cell.blank) return null;
|
|
1619
|
+
if (panel === "date") {
|
|
1620
|
+
selected = parseIsoDate(String(cell.value));
|
|
1621
|
+
return selected ? isoDate(selected) : null;
|
|
1622
|
+
}
|
|
1623
|
+
if (panel === "month") {
|
|
1624
|
+
month = Number(cell.value);
|
|
1625
|
+
panel = "date";
|
|
1626
|
+
return null;
|
|
1627
|
+
}
|
|
1628
|
+
year = Number(cell.value);
|
|
1629
|
+
panel = "month";
|
|
1630
|
+
return null;
|
|
1631
|
+
},
|
|
1632
|
+
setValue(value) {
|
|
1633
|
+
selected = parseIsoDate(value);
|
|
1634
|
+
if (selected) {
|
|
1635
|
+
year = selected.getFullYear();
|
|
1636
|
+
month = selected.getMonth();
|
|
1637
|
+
}
|
|
1638
|
+
panel = "date";
|
|
1639
|
+
}
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
// src/ui/components/date-picker/styles.ts
|
|
1644
|
+
var DATE_PICKER_STYLE_ID = "vela-date-picker-styles";
|
|
1645
|
+
var DATE_PICKER_CSS = `
|
|
1646
|
+
.vela-date-picker{color:var(--vela-fg);font:14px var(--vela-font);user-select:none;}
|
|
1647
|
+
.vela-date-picker [hidden]{display:none !important;}
|
|
1648
|
+
.vela-date-picker-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px;}
|
|
1649
|
+
.vela-date-picker-title{flex:1;display:flex;align-items:center;justify-content:center;gap:2px;min-width:0;}
|
|
1650
|
+
.vela-date-picker-switch{border:none;background:transparent;color:var(--vela-fg-bright);font:inherit;font-weight:600;font-size:14px;padding:2px 6px;border-radius:4px;cursor:pointer;}
|
|
1651
|
+
.vela-date-picker-switch:not(:disabled):hover{background:var(--vela-hover);}
|
|
1652
|
+
.vela-date-picker-switch:disabled{cursor:default;}
|
|
1653
|
+
.vela-date-picker-nav{width:24px;height:24px;border:none;background:transparent;color:var(--vela-fg-muted);border-radius:4px;padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:14px;}
|
|
1654
|
+
.vela-date-picker-nav:hover{background:var(--vela-hover);color:var(--vela-fg-bright);}
|
|
1655
|
+
.vela-date-picker-week,.vela-date-picker-grid{display:grid;grid-template-columns:repeat(7,28px);gap:2px;}
|
|
1656
|
+
.vela-date-picker-week{margin-bottom:4px;color:var(--vela-fg-muted);font-size:11px;text-align:center;}
|
|
1657
|
+
.vela-date-picker-week span{line-height:20px;}
|
|
1658
|
+
.vela-date-picker-blank{width:28px;height:28px;}
|
|
1659
|
+
.vela-date-picker-day{width:28px;height:28px;border:none;background:transparent;color:inherit;border-radius:4px;padding:0;cursor:pointer;font:inherit;font-size:14px;}
|
|
1660
|
+
.vela-date-picker-day:hover{background:var(--vela-hover);}
|
|
1661
|
+
.vela-date-picker-day[data-checked]{background:var(--vela-hover-strong);color:var(--vela-fg-bright);}
|
|
1662
|
+
.vela-date-picker-day[data-today]:not([data-checked]){box-shadow:inset 0 0 0 1px var(--vela-border-strong);}
|
|
1663
|
+
.vela-date-picker-cells{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;width:calc(7 * 28px + 6 * 2px);}
|
|
1664
|
+
.vela-date-picker-cell{height:36px;border:none;background:transparent;color:inherit;border-radius:4px;padding:0 4px;cursor:pointer;font:inherit;font-size:14px;}
|
|
1665
|
+
.vela-date-picker-cell:hover{background:var(--vela-hover);}
|
|
1666
|
+
.vela-date-picker-cell[data-checked]{background:var(--vela-hover-strong);color:var(--vela-fg-bright);}
|
|
1667
|
+
.vela-date-picker-cell[data-today]:not([data-checked]){box-shadow:inset 0 0 0 1px var(--vela-border-strong);}
|
|
1668
|
+
.vela-date-picker-cell[data-outside]{opacity:0.45;}
|
|
1669
|
+
`;
|
|
1670
|
+
|
|
1671
|
+
// src/ui/components/date-picker/view.ts
|
|
1672
|
+
var DatePicker = class {
|
|
1673
|
+
constructor(opts = {}) {
|
|
1674
|
+
this.opts = opts;
|
|
1675
|
+
const doc = document;
|
|
1676
|
+
injectStyles(DATE_PICKER_STYLE_ID, DATE_PICKER_CSS, doc);
|
|
1677
|
+
this.ctrl = datePickerController(opts);
|
|
1678
|
+
const button = (className) => {
|
|
1679
|
+
const b = doc.createElement("button");
|
|
1680
|
+
b.type = "button";
|
|
1681
|
+
b.className = className;
|
|
1682
|
+
return b;
|
|
1683
|
+
};
|
|
1684
|
+
this.prev = button("vela-date-picker-nav");
|
|
1685
|
+
this.prev.append(iconEl("chevron-left", doc));
|
|
1686
|
+
this.next = button("vela-date-picker-nav");
|
|
1687
|
+
this.next.append(iconEl("chevron-right", doc));
|
|
1688
|
+
this.monthBtn = button("vela-date-picker-switch");
|
|
1689
|
+
this.monthBtn.setAttribute("aria-label", "Choose month");
|
|
1690
|
+
this.yearBtn = button("vela-date-picker-switch");
|
|
1691
|
+
this.yearBtn.setAttribute("aria-label", "Choose year");
|
|
1692
|
+
const title = doc.createElement("div");
|
|
1693
|
+
title.className = "vela-date-picker-title";
|
|
1694
|
+
title.append(this.monthBtn, this.yearBtn);
|
|
1695
|
+
const head = doc.createElement("div");
|
|
1696
|
+
head.className = "vela-date-picker-head";
|
|
1697
|
+
head.append(this.prev, title, this.next);
|
|
1698
|
+
this.week = doc.createElement("div");
|
|
1699
|
+
this.week.className = "vela-date-picker-week";
|
|
1700
|
+
for (const d of WEEKDAY_LABELS) {
|
|
1701
|
+
const cell = doc.createElement("span");
|
|
1702
|
+
cell.textContent = d;
|
|
1703
|
+
this.week.appendChild(cell);
|
|
1704
|
+
}
|
|
1705
|
+
this.grid = doc.createElement("div");
|
|
1706
|
+
const on = (el, run) => el.addEventListener("click", (e) => {
|
|
1707
|
+
e.stopPropagation();
|
|
1708
|
+
run();
|
|
1709
|
+
this.paint();
|
|
1710
|
+
});
|
|
1711
|
+
on(this.prev, () => this.ctrl.step(-1));
|
|
1712
|
+
on(this.next, () => this.ctrl.step(1));
|
|
1713
|
+
on(this.monthBtn, () => this.ctrl.showMonths());
|
|
1714
|
+
on(this.yearBtn, () => this.ctrl.showYears());
|
|
1715
|
+
this.el = doc.createElement("div");
|
|
1716
|
+
this.el.className = "vela-date-picker";
|
|
1717
|
+
this.el.append(head, this.week, this.grid);
|
|
1718
|
+
this.paint();
|
|
1719
|
+
}
|
|
1720
|
+
get value() {
|
|
1721
|
+
return this.ctrl.value;
|
|
1722
|
+
}
|
|
1723
|
+
/** Rewrite the selection without emitting (the calendar opens on its month). */
|
|
1724
|
+
setValue(value) {
|
|
1725
|
+
this.ctrl.setValue(value);
|
|
1726
|
+
this.paint();
|
|
1727
|
+
}
|
|
1728
|
+
paint() {
|
|
1729
|
+
const doc = this.el.ownerDocument;
|
|
1730
|
+
const h = this.ctrl.header();
|
|
1731
|
+
this.monthBtn.hidden = !h.monthVisible;
|
|
1732
|
+
this.monthBtn.textContent = h.month;
|
|
1733
|
+
this.yearBtn.textContent = h.year;
|
|
1734
|
+
this.yearBtn.disabled = h.yearDisabled;
|
|
1735
|
+
const nav = this.ctrl.navLabels();
|
|
1736
|
+
this.prev.setAttribute("aria-label", nav.prev);
|
|
1737
|
+
this.next.setAttribute("aria-label", nav.next);
|
|
1738
|
+
const dates = this.ctrl.panel === "date";
|
|
1739
|
+
this.week.hidden = !dates;
|
|
1740
|
+
this.grid.className = dates ? "vela-date-picker-grid" : "vela-date-picker-cells";
|
|
1741
|
+
this.grid.replaceChildren(...this.ctrl.cells().map((cell) => this.cellEl(doc, cell, dates)));
|
|
1742
|
+
}
|
|
1743
|
+
cellEl(doc, cell, dates) {
|
|
1744
|
+
if (cell.blank) {
|
|
1745
|
+
const blank = doc.createElement("span");
|
|
1746
|
+
blank.className = "vela-date-picker-blank";
|
|
1747
|
+
return blank;
|
|
1748
|
+
}
|
|
1749
|
+
const b = doc.createElement("button");
|
|
1750
|
+
b.type = "button";
|
|
1751
|
+
b.className = dates ? "vela-date-picker-day" : "vela-date-picker-cell";
|
|
1752
|
+
b.textContent = cell.label;
|
|
1753
|
+
if (cell.checked) b.dataset.checked = "1";
|
|
1754
|
+
if (cell.today) b.dataset.today = "1";
|
|
1755
|
+
if (cell.outside) b.dataset.outside = "1";
|
|
1756
|
+
b.addEventListener("click", (e) => {
|
|
1757
|
+
e.stopPropagation();
|
|
1758
|
+
const picked = this.ctrl.choose(cell);
|
|
1759
|
+
if (picked) this.opts.onPick?.(picked);
|
|
1760
|
+
else this.paint();
|
|
1761
|
+
});
|
|
1762
|
+
return b;
|
|
1763
|
+
}
|
|
1764
|
+
};
|
|
1765
|
+
|
|
1508
1766
|
// src/ui/components/switch/controller.ts
|
|
1509
1767
|
function switchController(opts = {}) {
|
|
1510
1768
|
let checked = opts.checked ?? false;
|
|
@@ -2248,14 +2506,49 @@ function buildColorPicker(color, theme, onChange, options = {}) {
|
|
|
2248
2506
|
const knob = document.createElement("div");
|
|
2249
2507
|
knob.style.cssText = "position:absolute;top:50%;width:15px;height:15px;border-radius:50%;background:var(--vela-selected-bg);box-shadow:0 1px 3px rgba(0,0,0,0.55);transform:translate(-50%,-50%);pointer-events:none;";
|
|
2250
2508
|
track.appendChild(knob);
|
|
2251
|
-
const pctBox = document.createElement("
|
|
2252
|
-
pctBox.
|
|
2509
|
+
const pctBox = document.createElement("input");
|
|
2510
|
+
pctBox.type = "text";
|
|
2511
|
+
pctBox.inputMode = "numeric";
|
|
2512
|
+
pctBox.title = "Opacity (%)";
|
|
2513
|
+
pctBox.style.cssText = `width:46px;box-sizing:border-box;text-align:center;font:var(--vela-font-size-md) ${theme.fontFamily};color:var(--vela-fg);background:transparent;border:1px solid var(--vela-border);border-radius:5px;padding:3px 4px;outline:none;`;
|
|
2514
|
+
pctBox.addEventListener("focus", () => {
|
|
2515
|
+
pctBox.style.borderColor = "var(--vela-border-strong)";
|
|
2516
|
+
pctBox.select();
|
|
2517
|
+
});
|
|
2253
2518
|
opRow.append(track, pctBox);
|
|
2254
2519
|
const paintOpacity = () => {
|
|
2255
2520
|
track.style.background = `linear-gradient(to right, ${curHex}00, ${curHex}ff), ${CHECKER}`;
|
|
2256
2521
|
knob.style.left = `${curAlpha * 100}%`;
|
|
2257
|
-
pctBox.
|
|
2522
|
+
pctBox.value = `${Math.round(curAlpha * 100)}%`;
|
|
2258
2523
|
};
|
|
2524
|
+
const commitTyped = () => {
|
|
2525
|
+
pctBox.style.borderColor = "var(--vela-border)";
|
|
2526
|
+
const n = parseFloat(pctBox.value.replace("%", ""));
|
|
2527
|
+
if (Number.isFinite(n)) {
|
|
2528
|
+
const next = Math.max(0, Math.min(100, n)) / 100;
|
|
2529
|
+
if (Math.round(next * 100) !== Math.round(curAlpha * 100)) {
|
|
2530
|
+
curAlpha = next;
|
|
2531
|
+
paintOpacity();
|
|
2532
|
+
emit();
|
|
2533
|
+
return;
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
paintOpacity();
|
|
2537
|
+
};
|
|
2538
|
+
pctBox.addEventListener("change", commitTyped);
|
|
2539
|
+
pctBox.addEventListener("blur", () => {
|
|
2540
|
+
pctBox.style.borderColor = "var(--vela-border)";
|
|
2541
|
+
paintOpacity();
|
|
2542
|
+
});
|
|
2543
|
+
pctBox.addEventListener("keydown", (e) => {
|
|
2544
|
+
if (e.key === "Escape") return;
|
|
2545
|
+
e.stopPropagation();
|
|
2546
|
+
if (e.key === "Enter") {
|
|
2547
|
+
e.preventDefault();
|
|
2548
|
+
commitTyped();
|
|
2549
|
+
pctBox.blur();
|
|
2550
|
+
}
|
|
2551
|
+
});
|
|
2259
2552
|
let dragging = false;
|
|
2260
2553
|
const onDrag = (clientX) => {
|
|
2261
2554
|
const r = track.getBoundingClientRect();
|
|
@@ -2888,4 +3181,4 @@ function buildFieldControl(desc) {
|
|
|
2888
3181
|
return { el };
|
|
2889
3182
|
}
|
|
2890
3183
|
|
|
2891
|
-
export { CALLOUT_CSS, CALLOUT_STYLE_ID, CalloutBubble, ColorField, Dialog, FIELD_GAP_PX, GlyphSelect, Menu, NumberInput, Popover, STATIC_TOKENS, Select, Switch, TextArea, TextField, WIDTH_FIELD_OPTIONS, applyPlotOverlayTokens, applyThemeTokens, blendOver, buildColorPicker, buildFieldControl, buildPalette, calloutPanelRows, clampNumber, closeColorPopover, closeOpenPopovers, closeWidthPopover, closesPanel, colorField, colorPickerController, combineColor, decorateSelectScroll, dialogController, ensureUIHost, eventDismissedPopover, fieldGrid, fieldGridColumns, fieldRow, fieldSection, fieldSeparator, fillSelectList, glyphSelectController, hslHex, insetRect, intersectRects, isPopoverOpen, lineWidthGlyph, menuController, nextUid, numberInputController, openPopoverTrigger, openSelectList, placePopover, popoverController, runMachine, selectController, snapToStep, splitColor, switchController, textAreaController, textFieldController, themeTokens, toggleSelectList, transparencyChecker, viewportRect, widthField, widthFieldOptions };
|
|
3184
|
+
export { CALLOUT_CSS, CALLOUT_STYLE_ID, CalloutBubble, ColorField, DatePicker, Dialog, FIELD_GAP_PX, GlyphSelect, Menu, NumberInput, Popover, STATIC_TOKENS, Select, Switch, TextArea, TextField, WIDTH_FIELD_OPTIONS, applyPlotOverlayTokens, applyThemeTokens, blendOver, buildColorPicker, buildFieldControl, buildPalette, calloutPanelRows, clampNumber, closeColorPopover, closeOpenPopovers, closeWidthPopover, closesPanel, colorField, colorPickerController, combineColor, datePickerController, decorateSelectScroll, dialogController, ensureUIHost, eventDismissedPopover, fieldGrid, fieldGridColumns, fieldRow, fieldSection, fieldSeparator, fillSelectList, glyphSelectController, hslHex, insetRect, intersectRects, isPopoverOpen, isoDate, lineWidthGlyph, menuController, nextUid, normalizeDateInput, numberInputController, openPopoverTrigger, openSelectList, placePopover, popoverController, runMachine, selectController, snapToStep, splitColor, switchController, textAreaController, textFieldController, themeTokens, toggleSelectList, transparencyChecker, viewportRect, widthField, widthFieldOptions };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { x as Millis,
|
|
2
|
-
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-
|
|
1
|
+
import { x as Millis, ao as InputSchema, am as IndicatorMeta, P as PriceStyle, O as OHLCV, I as InputValue, l as IndicatorModel, k as MoveTarget, aH as PaneAxis, aW as SeriesSpec, ak as Fill, H as Background, aM as PriceLine, a7 as DrawingLine, a3 as DrawingBox, a6 as DrawingLabel, ab as DrawingPolyline, a8 as DrawingLinefill, ag as DrawingTable, h as IndicatorStatus, a as VisibleRange, c as VelaTheme, S as SerializedDrawing, z as DrawingTypeKey, y as SnapMode, a9 as DrawingMode, u as MarkClickEvent, e as IChartRenderer, R as RendererCapabilities, o as LegendActionView, p as LegendCalloutView, U as Unsubscribe, C as CrosshairEvent, r as ClickEvent, A as AxisLongPressEvent, v as DataWindowReadout, n as SymbolPickerFn, W as WallClock, bc as PaneInfo, aj as DrawingsOption, ad as DrawingSeriesGateway, D as Drawing, s as TimelineMark, t as MarkGroup, b as VelaOptions, F as AddIndicatorOptions, aG as MarketSwitch, E as MarketSnapshot, V as VisibleRangePreset, T as ThemeName } from './options-BnEPUuVV.cjs';
|
|
2
|
+
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-BrlxntPN.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A strategy's broker state at ONE bar — the flat summary a host reads while a script
|
|
@@ -474,6 +474,8 @@ interface NativeIndicatorContext {
|
|
|
474
474
|
readonly id: string;
|
|
475
475
|
readonly symbol: string;
|
|
476
476
|
readonly timeframe: string;
|
|
477
|
+
/** Whether the chart streams live data. False during a bar replay — entering and
|
|
478
|
+
* leaving replay RESTARTS the indicator, so this never changes within one context. */
|
|
477
479
|
readonly live: boolean;
|
|
478
480
|
/** The chart's trading session (`'regular'` | `'extended'`); undefined = regular /
|
|
479
481
|
* no session model. A session switch reloads the market and RESTARTS the
|
|
@@ -681,6 +683,129 @@ interface ScriptRunResult {
|
|
|
681
683
|
remove(): void;
|
|
682
684
|
}
|
|
683
685
|
|
|
686
|
+
/** Where a bar replay stands (`chart.replay.state`). */
|
|
687
|
+
interface ReplayState {
|
|
688
|
+
/** Replay mode is on: the chart shows history up to the cursor, live updates are paused.
|
|
689
|
+
* Stays on through a timeframe/session switch while the new bars load (`cursorTime`
|
|
690
|
+
* is null until the replay resumes on them). */
|
|
691
|
+
active: boolean;
|
|
692
|
+
/** Bars are being revealed on a timer (`play`), as opposed to paused / stepped by hand. */
|
|
693
|
+
playing: boolean;
|
|
694
|
+
/** Open time (epoch ms) of the newest bar on screen; null when replay is off. */
|
|
695
|
+
cursorTime: number | null;
|
|
696
|
+
/** Bars still hidden to the right of the cursor. */
|
|
697
|
+
remaining: number;
|
|
698
|
+
/** Open time (epoch ms) of the next bar a step completes — the one forming tick by tick,
|
|
699
|
+
* else the next hidden one; null when nothing is left or replay is off. Lets a host
|
|
700
|
+
* keep several charts on one clock (see `VelaWorkspace.replay`). */
|
|
701
|
+
nextTime: number | null;
|
|
702
|
+
/** Delay between two updates while playing (ms) — two bars, or two ticks with {@link ReplayControl.setTicks}. */
|
|
703
|
+
intervalMs: number;
|
|
704
|
+
}
|
|
705
|
+
/** Options for {@link ReplayControl.start}. */
|
|
706
|
+
interface ReplayStartOptions {
|
|
707
|
+
/**
|
|
708
|
+
* Epoch ms. The chart keeps every bar that opened at or before it and hides the rest.
|
|
709
|
+
* Older than the loaded history ⇒ the history is deepened first (clamped to the
|
|
710
|
+
* oldest bar the source serves).
|
|
711
|
+
*/
|
|
712
|
+
from: number;
|
|
713
|
+
}
|
|
714
|
+
/** Why a replay ended (`replay:end`). */
|
|
715
|
+
type ReplayEndReason = 'stopped' | 'finished' | 'market';
|
|
716
|
+
/** One intrabar update of a replayed bar ({@link ReplayControl.setTicks}). */
|
|
717
|
+
interface ReplayTick {
|
|
718
|
+
/** The price the forming candle closes at after this update. */
|
|
719
|
+
price: number;
|
|
720
|
+
/** The extremes traded since the previous update (default: `price`) — lets one update
|
|
721
|
+
* stand for a whole span, e.g. a lower-timeframe bar. */
|
|
722
|
+
high?: number;
|
|
723
|
+
low?: number;
|
|
724
|
+
/** Where the candle opens — read on a bar's first update only (default: `price`). */
|
|
725
|
+
open?: number;
|
|
726
|
+
/** Volume traded by this update. When no tick of a bar carries one, the bar's volume
|
|
727
|
+
* is spread evenly across its ticks. */
|
|
728
|
+
volume?: number;
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Where a replay gets the intrabar prices of a bar it is about to reveal: `bar` is the
|
|
732
|
+
* stored bar, `end` the open time of the bar after it (the span the ticks cover is
|
|
733
|
+
* `[bar.time, end)`), `signal` aborts when the replay moves on (seek, stop, new source).
|
|
734
|
+
* Prices come oldest first. An empty list — or a failure — reveals the bar whole.
|
|
735
|
+
*/
|
|
736
|
+
type ReplayTickSource = (bar: OHLCV, opts: {
|
|
737
|
+
end: number;
|
|
738
|
+
signal: AbortSignal;
|
|
739
|
+
}) => readonly ReplayTick[] | Promise<readonly ReplayTick[]>;
|
|
740
|
+
/** What the chart implements behind {@link ReplayControl}. */
|
|
741
|
+
interface ReplayController {
|
|
742
|
+
replayStart(opts: ReplayStartOptions): Promise<void>;
|
|
743
|
+
replayStep(): boolean;
|
|
744
|
+
replayStepUpdate(): boolean;
|
|
745
|
+
replayPlay(intervalMs?: number): void;
|
|
746
|
+
replayPause(): void;
|
|
747
|
+
replayStop(): void;
|
|
748
|
+
replayState(): ReplayState;
|
|
749
|
+
replayBounds(): ReplayBounds | null;
|
|
750
|
+
replaySetTicks(source: ReplayTickSource | null): void;
|
|
751
|
+
}
|
|
752
|
+
/** The open times of the oldest and newest bar a replay can start from (`chart.replay.bounds`). */
|
|
753
|
+
interface ReplayBounds {
|
|
754
|
+
first: number;
|
|
755
|
+
last: number;
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* The chart's bar-replay control surface (`chart.replay`) — sibling of `chart.data` /
|
|
759
|
+
* `chart.marks`. Rewinds the chart to a past bar and reveals the following bars one at a
|
|
760
|
+
* time, by hand or on a timer, from the history already in memory (nothing is refetched).
|
|
761
|
+
* Revealed bars travel the exact path of a live bar: indicators, chart-type engines and
|
|
762
|
+
* the `bar` event see them as new bars — but script alerts stay quiet (a replayed bar is
|
|
763
|
+
* history, not a live signal). Live updates pause for the duration; `stop()` (or
|
|
764
|
+
* revealing the last bar) restores the full history and resumes them. A timeframe or
|
|
765
|
+
* session switch carries the replay over to the new bars at the same point in time; a
|
|
766
|
+
* symbol switch ends it.
|
|
767
|
+
*/
|
|
768
|
+
declare class ReplayControl {
|
|
769
|
+
private readonly ctrl;
|
|
770
|
+
constructor(ctrl: ReplayController);
|
|
771
|
+
/**
|
|
772
|
+
* Enter replay (or seek, when already replaying) at `opts.from`. Resolves once the
|
|
773
|
+
* chart shows the rewound history — after any in-flight history load has finished.
|
|
774
|
+
* Starts paused; call {@link play} or {@link step}.
|
|
775
|
+
*/
|
|
776
|
+
start(opts: ReplayStartOptions): Promise<void>;
|
|
777
|
+
/** Reveal the next bar — or, mid-way through a bar played tick by tick, complete it.
|
|
778
|
+
* Returns false when replay is off or nothing is left. */
|
|
779
|
+
step(): boolean;
|
|
780
|
+
/** Reveal the next UPDATE: with {@link setTicks}, the next tick of the forming bar — or
|
|
781
|
+
* the next bar opened at its first tick (once its ticks are in, if still loading);
|
|
782
|
+
* otherwise the next whole bar, like {@link step}. Returns false when nothing is left. */
|
|
783
|
+
stepUpdate(): boolean;
|
|
784
|
+
/** Reveal one bar (one tick, with {@link setTicks}) every `intervalMs` (default: the last
|
|
785
|
+
* interval used, else 1000). Calling it again while playing changes the pace. */
|
|
786
|
+
play(intervalMs?: number): this;
|
|
787
|
+
pause(): this;
|
|
788
|
+
/** Leave replay: the full history comes back and live updates resume. Also cancels a
|
|
789
|
+
* `start()` still loading older history (the chart returns to its previous depth). */
|
|
790
|
+
stop(): this;
|
|
791
|
+
get state(): ReplayState;
|
|
792
|
+
/** The loaded history a replay can walk — hidden bars included while replaying. Null
|
|
793
|
+
* before any bar loaded. A start older than `first` deepens the history first. */
|
|
794
|
+
get bounds(): ReplayBounds | null;
|
|
795
|
+
/**
|
|
796
|
+
* Play each revealed bar as a series of intrabar updates instead of whole: while
|
|
797
|
+
* playing, the forming candle opens at the first tick, then every tick moves its close
|
|
798
|
+
* and stretches its high and low, exactly like a live tick — indicators, chart types
|
|
799
|
+
* and the `bar` event follow — and the last one settles it on the stored bar. The play
|
|
800
|
+
* interval is then the time between two TICKS: a bar lasts as many intervals as it
|
|
801
|
+
* has ticks (below ~16 ms, ticks are batched per frame). The next bar's ticks are
|
|
802
|
+
* requested while the current one plays; playback waits for them. `null` goes back to
|
|
803
|
+
* whole bars. Takes effect from the next bar; a bar forming when the source changes
|
|
804
|
+
* completes at once.
|
|
805
|
+
*/
|
|
806
|
+
setTicks(source: ReplayTickSource | null): this;
|
|
807
|
+
}
|
|
808
|
+
|
|
684
809
|
/** Chart-level events emitted on `chart.on(...)`. */
|
|
685
810
|
interface VelaEventMap extends Record<string, unknown> {
|
|
686
811
|
ready: undefined;
|
|
@@ -838,7 +963,7 @@ interface VelaEventMap extends Record<string, unknown> {
|
|
|
838
963
|
"context:changed": {
|
|
839
964
|
id: string;
|
|
840
965
|
};
|
|
841
|
-
/** A live tick: the forming bar was updated or a new bar appended. */
|
|
966
|
+
/** A live tick: the forming bar was updated or a new bar appended (a bar revealed by replay included). */
|
|
842
967
|
bar: OHLCV;
|
|
843
968
|
/**
|
|
844
969
|
* The visible time range moved (pan/zoom/fit — fires per applied change, NOT
|
|
@@ -865,8 +990,42 @@ interface VelaEventMap extends Record<string, unknown> {
|
|
|
865
990
|
oldestTime: number;
|
|
866
991
|
barsLoaded: number;
|
|
867
992
|
};
|
|
993
|
+
/** Replay mode began (or seeked): the chart shows history up to `cursorTime`, `remaining` bars are hidden. */
|
|
994
|
+
"replay:start": {
|
|
995
|
+
cursorTime: number;
|
|
996
|
+
remaining: number;
|
|
997
|
+
};
|
|
998
|
+
/** One hidden bar was revealed (it also fires `bar`, like a live bar). A bar played tick
|
|
999
|
+
* by tick steps once, when its last tick settles it. */
|
|
1000
|
+
"replay:step": {
|
|
1001
|
+
cursorTime: number;
|
|
1002
|
+
remaining: number;
|
|
1003
|
+
};
|
|
1004
|
+
/** An intrabar update of the bar forming at `cursorTime` (`chart.replay.setTicks`):
|
|
1005
|
+
* tick `index` of `count` is applied (batched updates report the last one). */
|
|
1006
|
+
"replay:tick": {
|
|
1007
|
+
cursorTime: number;
|
|
1008
|
+
index: number;
|
|
1009
|
+
count: number;
|
|
1010
|
+
};
|
|
1011
|
+
/** Timed reveal started, or its pace changed. */
|
|
1012
|
+
"replay:play": {
|
|
1013
|
+
intervalMs: number;
|
|
1014
|
+
};
|
|
1015
|
+
/** Timed reveal paused — `pause()`, or a seek (`start()` while playing). */
|
|
1016
|
+
"replay:pause": undefined;
|
|
1017
|
+
/**
|
|
1018
|
+
* Replay mode ended: `'stopped'` = `chart.replay.stop()`, `'finished'` = the last hidden
|
|
1019
|
+
* bar was revealed, `'market'` = a symbol switch replaced the history (a timeframe or
|
|
1020
|
+
* session switch carries the replay over instead). The full history
|
|
1021
|
+
* is back and live updates resumed.
|
|
1022
|
+
*/
|
|
1023
|
+
"replay:end": {
|
|
1024
|
+
reason: ReplayEndReason;
|
|
1025
|
+
};
|
|
868
1026
|
/** An indicator's script raised an alert. `indicator` names the source — the
|
|
869
|
-
* indicator's display title (what its legend row shows).
|
|
1027
|
+
* indicator's display title (what its legend row shows). Never fires for bars a
|
|
1028
|
+
* replay reveals (`chart.replay`). */
|
|
870
1029
|
alert: EngineAlert & {
|
|
871
1030
|
indicator?: string;
|
|
872
1031
|
};
|
|
@@ -1014,6 +1173,10 @@ declare class RendererControl {
|
|
|
1014
1173
|
* public seam host chrome (status lines, data windows) builds on.
|
|
1015
1174
|
*/
|
|
1016
1175
|
onCrosshairMove(cb: (e: CrosshairEvent) => void): Unsubscribe;
|
|
1176
|
+
/** A click — or a touch tap — on the plot, never the end of a pan: the open time of
|
|
1177
|
+
* the bar under it (`null` off the bars). On touch, where a tap moves no crosshair,
|
|
1178
|
+
* this is how an interaction learns which bar was chosen. */
|
|
1179
|
+
onClick(cb: (e: ClickEvent) => void): Unsubscribe;
|
|
1017
1180
|
/** Touch long-press on a price or time axis strip — silent no-op without the seam. */
|
|
1018
1181
|
onAxisLongPress(cb: (e: AxisLongPressEvent) => void): Unsubscribe;
|
|
1019
1182
|
/**
|
|
@@ -1487,6 +1650,7 @@ declare class Vela {
|
|
|
1487
1650
|
private readonly dataControl;
|
|
1488
1651
|
private readonly drawingsControl;
|
|
1489
1652
|
private readonly marksControl;
|
|
1653
|
+
private readonly replayControl;
|
|
1490
1654
|
constructor(container: HTMLElement | string, options?: VelaOptions, deps?: VelaDeps);
|
|
1491
1655
|
/**
|
|
1492
1656
|
* Register a scripting engine so `addIndicator({ language })` can run that
|
|
@@ -1622,6 +1786,14 @@ declare class Vela {
|
|
|
1622
1786
|
* model still fills but nothing paints (`chart.marks.supported`).
|
|
1623
1787
|
*/
|
|
1624
1788
|
get marks(): MarksControl;
|
|
1789
|
+
/**
|
|
1790
|
+
* The chart's bar-replay control surface: rewind to a past bar and reveal the
|
|
1791
|
+
* following ones by hand or on a timer, from the history already loaded —
|
|
1792
|
+
* `await chart.replay.start({ from })`, `chart.replay.play(2000)`, `chart.replay.step()`,
|
|
1793
|
+
* `chart.replay.stop()`. Revealed bars behave like live bars for indicators; live
|
|
1794
|
+
* updates pause meanwhile. Follow it with the `replay:*` events.
|
|
1795
|
+
*/
|
|
1796
|
+
get replay(): ReplayControl;
|
|
1625
1797
|
on<K extends keyof VelaEventMap>(event: K, handler: (payload: VelaEventMap[K]) => void): () => void;
|
|
1626
1798
|
/** The current visible time range (`from`/`to` in epoch-ms), or null before data loads. */
|
|
1627
1799
|
getVisibleRange(): VisibleRange | null;
|
|
@@ -1675,6 +1847,11 @@ interface WidgetContext {
|
|
|
1675
1847
|
* it. The dock stays exclusive: opening one closes whichever was showing. Unknown ids
|
|
1676
1848
|
* are ignored. The seam a plugin uses to open ITS OWN panel programmatically. */
|
|
1677
1849
|
togglePanel(id: string, open?: boolean): void;
|
|
1850
|
+
/** Dock `el` as a full-width strip in the shell's layout, between the chart area and
|
|
1851
|
+
* the bottom bar — the charts shrink to make room. Strips stack in docking order.
|
|
1852
|
+
* Returns the undock (removes `el`; a no-op once it has left the strip area). The
|
|
1853
|
+
* caller owns `el`, its content and styling. */
|
|
1854
|
+
dockStrip(el: HTMLElement): () => void;
|
|
1678
1855
|
/** The widget's root element — pass it as `host` when mounting kit components
|
|
1679
1856
|
* (Dialog/Menu/Tooltip) from an action; without an explicit host they portal to
|
|
1680
1857
|
* the body, OUTSIDE the theme variables. A multi-chart shell hands its own root. */
|
|
@@ -1743,6 +1920,11 @@ interface WidgetActionDescriptor {
|
|
|
1743
1920
|
* right after the style/layout dropdowns, styled like them (the spot and look of
|
|
1744
1921
|
* the built-in Indicators button, for actions that replace it). */
|
|
1745
1922
|
align?: 'left' | 'right';
|
|
1923
|
+
/** Topbar only: where the action goes on the MOBILE layout (the topbar is hidden
|
|
1924
|
+
* there). `'bar'` is an icon stop on the bottom bar; `'menu'` is a row in the
|
|
1925
|
+
* three-dots menu — a left (primary) action right after Layout, a right one at the
|
|
1926
|
+
* end. Default: `'bar'` for `align: 'left'`, `'menu'` otherwise. */
|
|
1927
|
+
mobile?: 'bar' | 'menu';
|
|
1746
1928
|
/** Runtime gate — omitted ⇒ always shown. */
|
|
1747
1929
|
when?: (ctx: WidgetContext) => boolean;
|
|
1748
1930
|
run: (ctx: WidgetContext) => void;
|
|
@@ -2040,4 +2222,4 @@ declare function unregisterDefaultEngine(language: string): void;
|
|
|
2040
2222
|
* language. The shell layers (widget, workspace cell) register exactly this result. */
|
|
2041
2223
|
declare function resolveEngines(overrides?: Record<string, EngineFactory>): Record<string, EngineFactory>;
|
|
2042
2224
|
|
|
2043
|
-
export { type
|
|
2225
|
+
export { type SidePanelButton as $, type NativeIndicatorDescriptor as A, type BarsChangeReason as B, type CellStateContext as C, type DrawingsDocument as D, type ExternalIndicatorEntry as E, type FetchSeries as F, type NativeIndicatorInfo as G, type NativeIndicatorOutput as H, type IndicatorHandle as I, type PreparedScript as J, RendererControl as K, type LegendActionDescriptor as L, MarksControl as M, type NativeIndicator as N, OVERRIDABLE_TOPBAR_IDS as O, type ParsedSymbol as P, ReplayControl as Q, type ReplayState as R, type ScriptingEngine as S, type ReplayEndReason as T, type ReplayStartOptions as U, Vela as V, type WidgetContext as W, type RunIndicatorResult as X, type SceneInspection as Y, type ScriptRunCause as Z, type ScriptRunResult as _, type ReplayBounds as a, type SidePanelDescriptor as a0, type SidePanelHandle as a1, type SidePanelHeader as a2, type StatePersistenceHandler as a3, type StrategyFill as a4, type StrategyState as a5, type StrategyTrade as a6, type SymbolRankingHook as a7, TypedEventBus as a8, type VelaDeps as a9, unregisterNativeIndicator as aA, unregisterSidePanel as aB, unregisterStatePersistence as aC, unregisterWidgetAction as aD, unregisterWidgetAttachment as aE, widgetActions as aF, widgetAttachments as aG, DEFAULT_PANEL_ORDER as aH, type VisibleBarRange as aa, type WidgetActionDescriptor as ab, type WidgetActionTarget as ac, type WidgetAttachment as ad, getNativeIndicator as ae, legendActions as af, legendCallouts as ag, nativeIndicatorDescriptors as ah, nativeIndicatorTypes as ai, registerDefaultEngine as aj, registerLegendAction as ak, registerLegendCallout as al, registerNativeIndicator as am, registerSidePanel as an, registerStatePersistence as ao, registerSymbolRanking as ap, registerWidgetAction as aq, registerWidgetAttachment as ar, resolveEngines as as, sidePanels as at, statePersistenceHandlers as au, symbolRanking as av, topbarActionOverride as aw, unregisterDefaultEngine as ax, unregisterLegendAction as ay, unregisterLegendCallout as az, type VelaEventMap as b, type ScriptRun as c, type Resolved as d, type ReplayTick as e, DataControl as f, type ReplayTickSource as g, type ContextSelect as h, DrawingsControl as i, type EngineAlert as j, type EngineCapabilities as k, type EngineContextSnapshot as l, type EngineFactory as m, type EngineWarning as n, type ExecutionHandlers as o, type ExecutionMarket as p, type ExecutionRequest as q, type ExecutionSession as r, type IndicatorEventMap as s, type IndicatorSummary as t, type LegendCalloutContent as u, type LegendCalloutDescriptor as v, type LegendCalloutItem as w, type LegendCalloutSpec as x, type LegendIndicatorInfo as y, type NativeIndicatorContext as z };
|