@luxalgo/vela 0.8.0 → 0.8.2
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 +1 -1
- package/README.md +16 -8
- package/dist/{DataProvider-BrlxntPN.d.cts → DataProvider-COGDs9Xg.d.cts} +1 -1
- package/dist/{DataProvider-DwFIoV4r.d.ts → DataProvider-DpOWZD8F.d.ts} +1 -1
- package/dist/{chunk-KA77UTRF.js → chunk-27UTYE7T.js} +25 -2
- package/dist/{chunk-EZ5FWVLA.js → chunk-DPAA3SRT.js} +94 -13
- package/dist/{chunk-BZQM2XO7.js → chunk-HKNO24GD.js} +13 -1
- package/dist/{chunk-2IAETM2I.js → chunk-NLDTVFOI.js} +79 -6
- package/dist/{chunk-E3GU6AUI.js → chunk-R2JMNIHY.js} +68 -23
- package/dist/{chunk-QBPUT5SU.js → chunk-T3DZIR5Y.js} +211 -54
- package/dist/{contributions-tjNExo1o.d.ts → contributions-Cgm9RJYP.d.cts} +38 -11
- package/dist/{contributions-CtlptxR8.d.cts → contributions-bWgwyiVi.d.ts} +38 -11
- package/dist/index.cjs +317 -62
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +4 -4
- package/dist/{options-BnEPUuVV.d.ts → options-NAUHiQEC.d.cts} +3 -3
- package/dist/{options-BnEPUuVV.d.cts → options-NAUHiQEC.d.ts} +3 -3
- package/dist/{plugin-BWxJRKzS.d.cts → plugin-CjjzZX2F.d.cts} +4 -4
- package/dist/{plugin-e2WUEtiI.d.ts → plugin-CqxWoDKS.d.ts} +4 -4
- package/dist/plugin.cjs +20 -6
- package/dist/plugin.d.cts +5 -5
- package/dist/plugin.d.ts +5 -5
- 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/{side-panel-HF0IAzwf.d.cts → side-panel-wMNfgyZb.d.cts} +13 -0
- package/dist/{side-panel-HF0IAzwf.d.ts → side-panel-wMNfgyZb.d.ts} +13 -0
- package/dist/{statusline-model-zKXtGIjj.d.ts → statusline-model-Dih6FGWP.d.ts} +3 -3
- package/dist/{statusline-model-DFY7tuHj.d.cts → statusline-model-Dpfpq54A.d.cts} +3 -3
- package/dist/ui.cjs +115 -5
- package/dist/ui.d.cts +28 -2
- package/dist/ui.d.ts +28 -2
- package/dist/ui.js +3 -3
- package/dist/vela.global.js +317 -62
- package/dist/vela.global.min.js +61 -68
- package/dist/widget.cjs +476 -85
- package/dist/widget.d.cts +20 -10
- package/dist/widget.d.ts +20 -10
- package/dist/widget.js +7 -7
- package/dist/workspace.cjs +476 -85
- package/dist/workspace.d.cts +6 -6
- package/dist/workspace.d.ts +6 -6
- package/dist/workspace.js +6 -6
- package/package.json +3 -3
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, SecondClock, resolveTimezone, timezoneMenuRows, isGroupRow, defaultMemberOf, groupKeyOf, groupMembers, LEGEND_AT_TOP_ATTR, normalizeSession, Vela, normalizeTimezone, isExchangeTimezone, TypedEventBus, timeframeToMs, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore } from './chunk-
|
|
2
|
-
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, mobilePlacement, widgetAttachments, getDrawingType, inputDeltas } from './chunk-
|
|
3
|
-
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-
|
|
4
|
-
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-
|
|
5
|
-
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, iconAt, SESSION_OFF, SESSION_POST, SESSION_PRE, icon, categoricalColor } from './chunk-
|
|
1
|
+
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, SecondClock, resolveTimezone, timezoneMenuRows, isGroupRow, defaultMemberOf, groupKeyOf, groupMembers, LEGEND_AT_TOP_ATTR, normalizeSession, Vela, normalizeTimezone, isExchangeTimezone, TypedEventBus, timeframeToMs, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore } from './chunk-T3DZIR5Y.js';
|
|
2
|
+
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, mobilePlacement, widgetAttachments, getDrawingType, inputDeltas } from './chunk-DPAA3SRT.js';
|
|
3
|
+
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-27UTYE7T.js';
|
|
4
|
+
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-NLDTVFOI.js';
|
|
5
|
+
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, iconAt, SESSION_OFF, SESSION_POST, SESSION_PRE, announceSurface, icon, categoricalColor } from './chunk-HKNO24GD.js';
|
|
6
6
|
import { baseOf } from './chunk-W4EJWLEO.js';
|
|
7
7
|
|
|
8
8
|
// src/widget/timeframe.ts
|
|
@@ -261,6 +261,7 @@ var LayoutPicker = class {
|
|
|
261
261
|
const panel = doc.createElement("div");
|
|
262
262
|
panel.className = "vela-lp";
|
|
263
263
|
this.layer.appendChild(panel);
|
|
264
|
+
this.panel = panel;
|
|
264
265
|
const cols = doc.createElement("div");
|
|
265
266
|
cols.className = "vela-lp-cols";
|
|
266
267
|
panel.appendChild(cols);
|
|
@@ -342,10 +343,12 @@ var LayoutPicker = class {
|
|
|
342
343
|
this.doc.addEventListener("pointerdown", this.onDocPointerDown, true);
|
|
343
344
|
this.doc.addEventListener("keydown", this.onDocKeydown, true);
|
|
344
345
|
this.opts.onOpenChange?.(true);
|
|
346
|
+
if (this.isOpen) announceSurface(this.panel, true, "popover", this.opts.trigger);
|
|
345
347
|
}
|
|
346
348
|
close() {
|
|
347
349
|
if (!this.isOpen) return;
|
|
348
350
|
this.isOpen = false;
|
|
351
|
+
announceSurface(this.panel, false, "popover", this.opts.trigger);
|
|
349
352
|
this.layer.style.display = "none";
|
|
350
353
|
this.opts.trigger.setAttribute("aria-expanded", "false");
|
|
351
354
|
this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
|
|
@@ -2813,19 +2816,22 @@ var PanelDock = class {
|
|
|
2813
2816
|
/**
|
|
2814
2817
|
* (Re)build the CONTRIBUTED panels from the registry — call once after the built-ins, and
|
|
2815
2818
|
* again on `refreshActions()` so a late registration appears. Contributed panels that are
|
|
2816
|
-
* gone from the registry are dropped
|
|
2817
|
-
* descriptor
|
|
2819
|
+
* gone from the registry are dropped and a REPLACED descriptor is rebuilt; a panel whose
|
|
2820
|
+
* descriptor is unchanged stays mounted as it is, so its content and state survive.
|
|
2818
2821
|
*/
|
|
2819
2822
|
refresh() {
|
|
2820
2823
|
const openBefore = this.openId;
|
|
2821
|
-
|
|
2822
|
-
for (const
|
|
2824
|
+
const registered = sidePanels();
|
|
2825
|
+
for (const entry of [...this.entries]) if (entry.contributed && !registered.includes(entry.desc)) this.drop(entry);
|
|
2826
|
+
for (const desc of registered) {
|
|
2827
|
+
if (this.entries.some((e) => e.desc === desc)) continue;
|
|
2823
2828
|
const panel = new SidePanel(this.host, desc.title, `vela-panel-${desc.id}`, {
|
|
2824
2829
|
width: desc.width,
|
|
2825
2830
|
resizable: desc.resizable,
|
|
2826
2831
|
minWidth: desc.minWidth,
|
|
2827
2832
|
maxWidth: desc.maxWidth,
|
|
2828
|
-
overlay: desc.overlay
|
|
2833
|
+
overlay: desc.overlay,
|
|
2834
|
+
maximizable: desc.maximizable
|
|
2829
2835
|
});
|
|
2830
2836
|
const entry = {
|
|
2831
2837
|
id: desc.id,
|
|
@@ -2833,10 +2839,19 @@ var PanelDock = class {
|
|
|
2833
2839
|
icon: desc.icon,
|
|
2834
2840
|
order: desc.order ?? DEFAULT_PANEL_ORDER,
|
|
2835
2841
|
panel,
|
|
2836
|
-
contributed: true
|
|
2842
|
+
contributed: true,
|
|
2843
|
+
desc
|
|
2837
2844
|
};
|
|
2838
2845
|
try {
|
|
2839
|
-
|
|
2846
|
+
const header = {
|
|
2847
|
+
slot: panel.headerSlot,
|
|
2848
|
+
setTitle: (t) => panel.setTitle(t),
|
|
2849
|
+
get maximized() {
|
|
2850
|
+
return panel.maximized;
|
|
2851
|
+
},
|
|
2852
|
+
setMaximized: (on) => panel.setMaximized(on)
|
|
2853
|
+
};
|
|
2854
|
+
entry.handle = desc.mount(this.deps.context(), panel.content, header) ?? void 0;
|
|
2840
2855
|
if (this.chart) entry.handle?.onChart?.(this.chart);
|
|
2841
2856
|
} catch (err) {
|
|
2842
2857
|
console.warn(`[vela] side panel "${desc.id}" failed to mount`, err);
|
|
@@ -3652,7 +3667,12 @@ var TimeframeQuick = class {
|
|
|
3652
3667
|
content: (body) => body.append(this.input, this.hint),
|
|
3653
3668
|
onOpenChange: (open) => opts.onOpenChange?.(open)
|
|
3654
3669
|
});
|
|
3655
|
-
this.input.addEventListener("input", () =>
|
|
3670
|
+
this.input.addEventListener("input", () => {
|
|
3671
|
+
const { selectionStart, selectionEnd } = this.input;
|
|
3672
|
+
this.input.value = this.input.value.toUpperCase();
|
|
3673
|
+
this.input.setSelectionRange(selectionStart, selectionEnd);
|
|
3674
|
+
this.renderHint();
|
|
3675
|
+
});
|
|
3656
3676
|
this.input.addEventListener("keydown", (e) => {
|
|
3657
3677
|
if (e.key !== "Enter") return;
|
|
3658
3678
|
const parsed = parseTimeframe(this.input.value);
|
|
@@ -3664,7 +3684,7 @@ var TimeframeQuick = class {
|
|
|
3664
3684
|
}
|
|
3665
3685
|
open(seed = "") {
|
|
3666
3686
|
this.dialog.show();
|
|
3667
|
-
this.input.value = seed;
|
|
3687
|
+
this.input.value = seed.toUpperCase();
|
|
3668
3688
|
this.renderHint();
|
|
3669
3689
|
setTimeout(() => {
|
|
3670
3690
|
this.input.focus();
|
|
@@ -3682,7 +3702,7 @@ var TimeframeQuick = class {
|
|
|
3682
3702
|
this.open(text);
|
|
3683
3703
|
return;
|
|
3684
3704
|
}
|
|
3685
|
-
this.input.value += text;
|
|
3705
|
+
this.input.value += text.toUpperCase();
|
|
3686
3706
|
this.renderHint();
|
|
3687
3707
|
}
|
|
3688
3708
|
close() {
|
|
@@ -3695,7 +3715,7 @@ var TimeframeQuick = class {
|
|
|
3695
3715
|
const raw = this.input.value.trim();
|
|
3696
3716
|
const parsed = parseTimeframe(raw);
|
|
3697
3717
|
if (!raw) {
|
|
3698
|
-
this.hint.textContent = "e.g. 15,
|
|
3718
|
+
this.hint.textContent = "e.g. 15, 4H, D, 3M";
|
|
3699
3719
|
delete this.hint.dataset.invalid;
|
|
3700
3720
|
} else if (parsed.valid) {
|
|
3701
3721
|
this.hint.textContent = parsed.label ?? "";
|
|
@@ -3798,7 +3818,7 @@ var ShortcutsHelp = class {
|
|
|
3798
3818
|
addRow("Delete the drawing under the cursor", ["Middle-click"]);
|
|
3799
3819
|
const s = doc.createElement("div");
|
|
3800
3820
|
s.className = "vela-sh-static";
|
|
3801
|
-
s.textContent = "Typing a letter opens the symbol search; typing a digit opens the timeframe entry.";
|
|
3821
|
+
s.textContent = "Typing a letter or 0 opens the symbol search; typing a digit from 1 to 9 opens the timeframe entry.";
|
|
3802
3822
|
this.list.appendChild(s);
|
|
3803
3823
|
}
|
|
3804
3824
|
};
|
|
@@ -4218,6 +4238,9 @@ var CSS10 = `
|
|
|
4218
4238
|
.vela-statusline .vela-sl-market { align-self: center; display: inline-flex; }
|
|
4219
4239
|
.vela-statusline .vela-sl-market > [hidden] { display: none !important; }
|
|
4220
4240
|
.vela-statusline .vela-sl-replay-badge, .vela-statusline .vela-sl-replay-badge svg { display: block; width: 16px; height: 16px; }
|
|
4241
|
+
/* Tabular figures: every digit has one advance, so a readout whose text changes only in
|
|
4242
|
+
* its digits keeps its width \u2014 render() skips the ladder for those (see widthKey). */
|
|
4243
|
+
.vela-statusline .vela-sl-values { font-variant-numeric: tabular-nums; }
|
|
4221
4244
|
.vela-statusline .vela-sl-ohlc { display: flex; gap: var(--vela-space-1); color: var(--vela-fg-muted); }
|
|
4222
4245
|
.vela-statusline .vela-sl-ohlc b { color: var(--vela-fg); font-weight: 500; }
|
|
4223
4246
|
/* The change value wears the SAME ink as the OHLC values (set inline per render) \u2014
|
|
@@ -4335,6 +4358,10 @@ var Statusline = class {
|
|
|
4335
4358
|
this.fitRO = null;
|
|
4336
4359
|
/** The ladder rung currently applied — see {@link fit}. */
|
|
4337
4360
|
this.layout = { stacked: false, level: "full" };
|
|
4361
|
+
/** The readout {@link widthKey} the applied rung was fitted to. */
|
|
4362
|
+
this.fitKey = null;
|
|
4363
|
+
/** Web fonts landing after the last fit change every width without a resize. */
|
|
4364
|
+
this.onFontsLoaded = () => this.fit();
|
|
4338
4365
|
this.onContextMenu = (e) => {
|
|
4339
4366
|
if (!this.menu || !this.menuHooks) return;
|
|
4340
4367
|
e.preventDefault();
|
|
@@ -4398,6 +4425,7 @@ var Statusline = class {
|
|
|
4398
4425
|
this.fitRO = new ResizeObserver(() => this.fit());
|
|
4399
4426
|
this.fitRO.observe(host);
|
|
4400
4427
|
}
|
|
4428
|
+
doc.fonts?.addEventListener("loadingdone", this.onFontsLoaded);
|
|
4401
4429
|
this.marketTip = new Tooltip(this.marketEl, { content: MARKET_LABELS.open, placement: "bottom" });
|
|
4402
4430
|
this.eyeTip = new Tooltip(this.eyeEl, { content: "Show chart", placement: "bottom" });
|
|
4403
4431
|
this.setMarketStatus("open");
|
|
@@ -4450,6 +4478,7 @@ var Statusline = class {
|
|
|
4450
4478
|
* (detached host, node tests) nothing overflows, so the widest rung stays.
|
|
4451
4479
|
*/
|
|
4452
4480
|
fit() {
|
|
4481
|
+
this.fitKey = this.widthKey();
|
|
4453
4482
|
this.syncParts();
|
|
4454
4483
|
const seg = segmentVisibility(this.parts, this.chartHidden);
|
|
4455
4484
|
const overflows = () => this.el.scrollWidth > this.el.clientWidth;
|
|
@@ -4606,6 +4635,7 @@ var Statusline = class {
|
|
|
4606
4635
|
this.detach();
|
|
4607
4636
|
this.fitRO?.disconnect();
|
|
4608
4637
|
this.fitRO = null;
|
|
4638
|
+
this.el.ownerDocument.fonts?.removeEventListener("loadingdone", this.onFontsLoaded);
|
|
4609
4639
|
this.el.removeEventListener("contextmenu", this.onContextMenu);
|
|
4610
4640
|
this.menu?.destroy();
|
|
4611
4641
|
this.menu = null;
|
|
@@ -4621,7 +4651,22 @@ var Statusline = class {
|
|
|
4621
4651
|
}
|
|
4622
4652
|
render() {
|
|
4623
4653
|
if (this.menuHooks) this.setChartHidden(!this.menuHooks.chartVisible());
|
|
4624
|
-
this.
|
|
4654
|
+
if (this.widthKey() === this.fitKey) this.renderValues();
|
|
4655
|
+
else this.fit();
|
|
4656
|
+
}
|
|
4657
|
+
/** Everything the readout's width depends on, at every rung: its shape, and each
|
|
4658
|
+
* value's sign, digit count and decimals (the digits themselves are tabular — see
|
|
4659
|
+
* the CSS; the grouping commas follow from the digit count). `toFixed` carries all
|
|
4660
|
+
* three at a fraction of the locale formatter's cost — this runs per pointer move.
|
|
4661
|
+
* The parts, the host's size and the fonts re-fit through their own paths. */
|
|
4662
|
+
widthKey() {
|
|
4663
|
+
const bar = this.hoverBar ?? this.lastBar;
|
|
4664
|
+
if (!bar) return this.readout;
|
|
4665
|
+
const dp = decimalsFor(bar.close);
|
|
4666
|
+
const diff = bar.close - bar.open;
|
|
4667
|
+
const text = [bar.open, bar.high, bar.low, bar.close, diff].map((v) => v.toFixed(dp));
|
|
4668
|
+
text.push((diff / bar.open * 100).toFixed(2));
|
|
4669
|
+
return `${this.readout} ${text.join(" ")}`.replace(/\d/g, "0");
|
|
4625
4670
|
}
|
|
4626
4671
|
/** Write the value readout for the current bar at the current ladder level. */
|
|
4627
4672
|
renderValues() {
|
|
@@ -6424,7 +6469,7 @@ var ChartCell = class {
|
|
|
6424
6469
|
* then the manifest in the host's own order. */
|
|
6425
6470
|
libraryRows() {
|
|
6426
6471
|
return [
|
|
6427
|
-
...this.supportedNatives().map((n) => ({ name: n.title, category: "
|
|
6472
|
+
...this.supportedNatives().map((n) => ({ name: n.title, category: "Built-in", native: true, nativeType: n.type, beta: n.beta })),
|
|
6428
6473
|
...this.manifest.map((e) => ({ name: e.name, language: e.language, category: e.category }))
|
|
6429
6474
|
];
|
|
6430
6475
|
}
|
|
@@ -8676,11 +8721,11 @@ function resolveTyping(key, open) {
|
|
|
8676
8721
|
if (open.dialogs > 0) {
|
|
8677
8722
|
if (key.length !== 1) return null;
|
|
8678
8723
|
if (open.symbolSearch) return { target: "symbol", text: key.toUpperCase() };
|
|
8679
|
-
if (open.timeframeEntry) return { target: "timeframe", text: key };
|
|
8724
|
+
if (open.timeframeEntry) return { target: "timeframe", text: key.toUpperCase() };
|
|
8680
8725
|
return null;
|
|
8681
8726
|
}
|
|
8682
|
-
if (/^[a-zA-
|
|
8683
|
-
if (/^[
|
|
8727
|
+
if (/^[a-zA-Z0]$/.test(key)) return { target: "symbol", text: key.toUpperCase() };
|
|
8728
|
+
if (/^[1-9]$/.test(key)) return { target: "timeframe", text: key };
|
|
8684
8729
|
return null;
|
|
8685
8730
|
}
|
|
8686
8731
|
var VelaWorkspace = class {
|
|
@@ -10418,7 +10463,7 @@ var VelaWorkspace = class {
|
|
|
10418
10463
|
}
|
|
10419
10464
|
});
|
|
10420
10465
|
}
|
|
10421
|
-
/** Bare-typing router: letters → symbol search (seeded), digits → timeframe entry. */
|
|
10466
|
+
/** Bare-typing router: letters and `0` → symbol search (seeded), digits 1–9 → timeframe entry. */
|
|
10422
10467
|
routeTyping(ev) {
|
|
10423
10468
|
if (this.destroyed) return;
|
|
10424
10469
|
if (ev.ctrlKey || ev.metaKey || ev.altKey) return;
|