@luxalgo/vela 0.7.4 → 0.7.5
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/dist/{DataProvider-CVpN5sCq.d.ts → DataProvider-DLeFs1gE.d.ts} +1 -1
- package/dist/{DataProvider-RF1axuy1.d.cts → DataProvider-Dut6lXGM.d.cts} +1 -1
- package/dist/{chunk-DUURH3RN.js → chunk-MCLI6B3S.js} +226 -66
- package/dist/{chunk-CSFNKXUW.js → chunk-MNG5XPLV.js} +6 -1
- package/dist/{contributions-CspPrMAJ.d.ts → contributions-CEkgJKTU.d.ts} +7 -3
- package/dist/{contributions-DpZeu7KP.d.cts → contributions-DYtiRtES.d.cts} +7 -3
- package/dist/index.cjs +226 -66
- package/dist/index.d.cts +19 -6
- package/dist/index.d.ts +19 -6
- package/dist/index.js +1 -1
- package/dist/{options-XVpfr9HV.d.cts → options-DNBoMKkX.d.cts} +8 -0
- package/dist/{options-XVpfr9HV.d.ts → options-DNBoMKkX.d.ts} +8 -0
- package/dist/{plugin-BoLOkblF.d.ts → plugin-CLn--oP6.d.ts} +3 -3
- package/dist/{plugin-D07HD2GL.d.cts → plugin-DtkeQVAO.d.cts} +3 -3
- package/dist/plugin.d.cts +4 -4
- package/dist/plugin.d.ts +4 -4
- 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-CPa_hmhd.d.ts → statusline-model-DypGXjtr.d.ts} +3 -3
- package/dist/{statusline-model-Bd4qKuD6.d.cts → statusline-model-gA__yaog.d.cts} +3 -3
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/vela.global.js +226 -66
- package/dist/vela.global.min.js +53 -49
- package/dist/widget.cjs +231 -66
- package/dist/widget.d.cts +6 -6
- package/dist/widget.d.ts +6 -6
- package/dist/widget.js +3 -3
- package/dist/workspace.cjs +231 -66
- package/dist/workspace.d.cts +5 -5
- package/dist/workspace.d.ts +5 -5
- package/dist/workspace.js +2 -2
- package/package.json +1 -1
package/dist/workspace.cjs
CHANGED
|
@@ -5061,6 +5061,17 @@ function hasOwnCandlePaint(style) {
|
|
|
5061
5061
|
for (const t of chartTypes()) if (t.id === style) return (t.basePainting ?? "candles") === "candles";
|
|
5062
5062
|
return false;
|
|
5063
5063
|
}
|
|
5064
|
+
var CANDLE_OVERRIDE_KEYS = [
|
|
5065
|
+
"candleUpColor",
|
|
5066
|
+
"candleDownColor",
|
|
5067
|
+
"candleBodyVisible",
|
|
5068
|
+
"candleBorderVisible",
|
|
5069
|
+
"candleBorderUpColor",
|
|
5070
|
+
"candleBorderDownColor",
|
|
5071
|
+
"candleWickVisible",
|
|
5072
|
+
"candleWickUpColor",
|
|
5073
|
+
"candleWickDownColor"
|
|
5074
|
+
];
|
|
5064
5075
|
function candleOverrideFor(style, bags) {
|
|
5065
5076
|
if (!hasOwnCandlePaint(style)) return null;
|
|
5066
5077
|
const bag = bags[style] ?? {};
|
|
@@ -5132,7 +5143,7 @@ function clampLevel(v) {
|
|
|
5132
5143
|
function clampSpacing(v) {
|
|
5133
5144
|
return v < 0.1 ? 0.1 : v > 10 ? 10 : v;
|
|
5134
5145
|
}
|
|
5135
|
-
function factoryResetConfig(factory) {
|
|
5146
|
+
function factoryResetConfig(factory, priceStyle = factory.series.style) {
|
|
5136
5147
|
const bag = {};
|
|
5137
5148
|
for (const t of chartTypes()) {
|
|
5138
5149
|
const section = t.settings;
|
|
@@ -5154,10 +5165,16 @@ function factoryResetConfig(factory) {
|
|
|
5154
5165
|
if (!section.instances) addRows(section.rows);
|
|
5155
5166
|
bag[t.id] = defaults2;
|
|
5156
5167
|
}
|
|
5168
|
+
for (const t of chartTypes()) {
|
|
5169
|
+
if (!hasOwnCandlePaint(t.id)) continue;
|
|
5170
|
+
const defaults2 = bag[t.id] ?? {};
|
|
5171
|
+
for (const key of CANDLE_OVERRIDE_KEYS) defaults2[key] = null;
|
|
5172
|
+
bag[t.id] = defaults2;
|
|
5173
|
+
}
|
|
5157
5174
|
for (const [typeId, vals] of Object.entries(factory.chartTypes)) {
|
|
5158
5175
|
bag[typeId] = { ...bag[typeId] ?? {}, ...vals };
|
|
5159
5176
|
}
|
|
5160
|
-
return { ...factory, chartTypes: bag };
|
|
5177
|
+
return { ...factory, chartTypes: bag, series: { ...factory.series, style: priceStyle } };
|
|
5161
5178
|
}
|
|
5162
5179
|
function mergeConfig(base, patch) {
|
|
5163
5180
|
const p = asObject(patch);
|
|
@@ -18585,6 +18602,42 @@ function presetToRange(preset, bars) {
|
|
|
18585
18602
|
return { from: Math.max(first, from), to: last };
|
|
18586
18603
|
}
|
|
18587
18604
|
|
|
18605
|
+
// src/core/marks/visibility.ts
|
|
18606
|
+
function markGroupOwnVisible(choices, groupId, groups) {
|
|
18607
|
+
const chosen = choices[groupId];
|
|
18608
|
+
if (typeof chosen === "boolean") return chosen;
|
|
18609
|
+
return groups.find((g) => g.id === groupId)?.visible !== false;
|
|
18610
|
+
}
|
|
18611
|
+
function markGroupVisible(choices, groupId, groups) {
|
|
18612
|
+
if (groupId === void 0) return true;
|
|
18613
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18614
|
+
let id = groupId;
|
|
18615
|
+
while (id !== void 0 && !seen.has(id)) {
|
|
18616
|
+
seen.add(id);
|
|
18617
|
+
if (!markGroupOwnVisible(choices, id, groups)) return false;
|
|
18618
|
+
const parent = groups.find((g) => g.id === id)?.parent;
|
|
18619
|
+
id = parent !== void 0 && groups.some((g) => g.id === parent) ? parent : void 0;
|
|
18620
|
+
}
|
|
18621
|
+
return true;
|
|
18622
|
+
}
|
|
18623
|
+
function markGroupRows(groups) {
|
|
18624
|
+
const ids = new Set(groups.map((g) => g.id));
|
|
18625
|
+
const out = [];
|
|
18626
|
+
const placed = /* @__PURE__ */ new Set();
|
|
18627
|
+
const place = (group, depth) => {
|
|
18628
|
+
if (placed.has(group.id)) return;
|
|
18629
|
+
placed.add(group.id);
|
|
18630
|
+
out.push({ group, depth });
|
|
18631
|
+
for (const child of groups) if (child.parent === group.id && child.id !== group.id) place(child, depth + 1);
|
|
18632
|
+
};
|
|
18633
|
+
for (const g of groups) {
|
|
18634
|
+
const parentKnown = g.parent !== void 0 && ids.has(g.parent) && g.parent !== g.id;
|
|
18635
|
+
if (!parentKnown) place(g, 0);
|
|
18636
|
+
}
|
|
18637
|
+
for (const g of groups) place(g, 0);
|
|
18638
|
+
return out;
|
|
18639
|
+
}
|
|
18640
|
+
|
|
18588
18641
|
// src/core/marks/MarksController.ts
|
|
18589
18642
|
var MarksController = class {
|
|
18590
18643
|
constructor(renderer, events) {
|
|
@@ -18629,6 +18682,7 @@ var MarksController = class {
|
|
|
18629
18682
|
defineGroup(group) {
|
|
18630
18683
|
if (!group || typeof group.id !== "string" || group.id.length === 0) throw new Error("[vela] marks.defineGroup: `id` must be a non-empty string");
|
|
18631
18684
|
if (typeof group.label !== "string") throw new Error(`[vela] marks.defineGroup: group "${group.id}" needs a string \`label\``);
|
|
18685
|
+
if (group.parent !== void 0 && (typeof group.parent !== "string" || group.parent.length === 0)) throw new Error(`[vela] marks.defineGroup: group "${group.id}" has a \`parent\` that is not a group id`);
|
|
18632
18686
|
this.groups.set(group.id, { ...group });
|
|
18633
18687
|
this.sync();
|
|
18634
18688
|
}
|
|
@@ -18648,12 +18702,16 @@ var MarksController = class {
|
|
|
18648
18702
|
}
|
|
18649
18703
|
this.renderer.applyFeature("marks", { groups: { [id]: visible } });
|
|
18650
18704
|
}
|
|
18651
|
-
/**
|
|
18705
|
+
/**
|
|
18706
|
+
* A group's effective visibility: its own switch — the user's (persisted) choice, else
|
|
18707
|
+
* the declared default, else visible — AND every ancestor's, so a child under a
|
|
18708
|
+
* switched-off parent reads hidden whatever its own choice says.
|
|
18709
|
+
*/
|
|
18652
18710
|
isGroupVisible(id) {
|
|
18653
18711
|
const state = this.renderer.readFeature("marks");
|
|
18654
|
-
const
|
|
18655
|
-
if (typeof
|
|
18656
|
-
return this.groups.
|
|
18712
|
+
const groups = {};
|
|
18713
|
+
for (const [gid, v] of Object.entries(state?.groups ?? {})) if (typeof v === "boolean") groups[gid] = v;
|
|
18714
|
+
return markGroupVisible(groups, id, [...this.groups.values()]);
|
|
18657
18715
|
}
|
|
18658
18716
|
destroy() {
|
|
18659
18717
|
for (const unsub of this.subs) unsub();
|
|
@@ -25642,11 +25700,8 @@ function mergeMarksState(base, patch) {
|
|
|
25642
25700
|
for (const [id, v] of Object.entries(g)) if (typeof v === "boolean") groups[id] = v;
|
|
25643
25701
|
return { visible: typeof p.visible === "boolean" ? p.visible : base.visible, groups };
|
|
25644
25702
|
}
|
|
25645
|
-
function
|
|
25646
|
-
|
|
25647
|
-
const chosen = state.groups[groupId];
|
|
25648
|
-
if (typeof chosen === "boolean") return chosen;
|
|
25649
|
-
return groups.find((g) => g.id === groupId)?.visible !== false;
|
|
25703
|
+
function markGroupVisible2(state, groupId, groups) {
|
|
25704
|
+
return markGroupVisible(state.groups, groupId, groups);
|
|
25650
25705
|
}
|
|
25651
25706
|
|
|
25652
25707
|
// src/renderers/native/core/SceneGraph.ts
|
|
@@ -27822,13 +27877,29 @@ function paintMarkLane(ctx, layout, deps) {
|
|
|
27822
27877
|
const img = deps.icons.get(mark.glyph.icon, ink, symbolPx, deps.dpr);
|
|
27823
27878
|
if (img) ctx.drawImage(img, center.x - symbolPx / 2, center.y - symbolPx / 2, symbolPx, symbolPx);
|
|
27824
27879
|
} else if (mark.glyph.letter) {
|
|
27880
|
+
const letter = mark.glyph.letter.slice(0, 2);
|
|
27825
27881
|
ctx.fillStyle = ink;
|
|
27826
|
-
|
|
27827
|
-
ctx.
|
|
27882
|
+
let px = letterFontPx(size, letter);
|
|
27883
|
+
ctx.font = `600 ${px}px ${deps.fontFamily}`;
|
|
27884
|
+
if (letter.length > 1) {
|
|
27885
|
+
px = fitLetterPx(px, ctx.measureText(letter).width, symbolInnerWidth(shape, size));
|
|
27886
|
+
ctx.font = `600 ${px}px ${deps.fontFamily}`;
|
|
27887
|
+
}
|
|
27888
|
+
ctx.fillText(letter, center.x, center.y + 0.5);
|
|
27828
27889
|
}
|
|
27829
27890
|
}
|
|
27830
27891
|
ctx.restore();
|
|
27831
27892
|
}
|
|
27893
|
+
function letterFontPx(size, letter) {
|
|
27894
|
+
return Math.round(size * (letter.length > 1 ? 0.38 : 0.58));
|
|
27895
|
+
}
|
|
27896
|
+
function symbolInnerWidth(shape, size) {
|
|
27897
|
+
return (shape === "pin" ? size * 0.82 : size) - 3;
|
|
27898
|
+
}
|
|
27899
|
+
function fitLetterPx(px, width, inner) {
|
|
27900
|
+
if (!(width > inner) || !(width > 0)) return px;
|
|
27901
|
+
return Math.max(4, Math.floor(px * inner / width));
|
|
27902
|
+
}
|
|
27832
27903
|
function traceShape(ctx, shape, x, y, size) {
|
|
27833
27904
|
const r = size / 2;
|
|
27834
27905
|
ctx.beginPath();
|
|
@@ -28030,7 +28101,7 @@ var ChromeRenderer = class {
|
|
|
28030
28101
|
this.markLayout = layoutMarkLane({
|
|
28031
28102
|
marks: scene.timelineMarks,
|
|
28032
28103
|
groups: scene.markGroups,
|
|
28033
|
-
hidden: (groupId) => !
|
|
28104
|
+
hidden: (groupId) => !markGroupVisible2(scene.marks, groupId, scene.markGroups),
|
|
28034
28105
|
barTimes: this.barTimes(scene),
|
|
28035
28106
|
intervalMs: coords.barInterval,
|
|
28036
28107
|
xOf: (bar) => coords.logicalToX(bar),
|
|
@@ -28720,6 +28791,10 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
28720
28791
|
muted and non-interactive. Applied to each row's children so it survives display:contents;
|
|
28721
28792
|
!important beats the inline opacity on labels. */
|
|
28722
28793
|
.vela-sd-soft>*{opacity:0.4 !important;pointer-events:none !important;}
|
|
28794
|
+
/* A mark group nested under a parent group on the Events tab: indented one step per level
|
|
28795
|
+
(--vela-sd-depth). The indent rides the first child (the switch) as a MARGIN \u2014 padding
|
|
28796
|
+
would push the switch's own tick out of its box. */
|
|
28797
|
+
.vela-sd-nested>*:first-child{margin-left:calc(var(--vela-sd-depth,1)*24px);}
|
|
28723
28798
|
/* \u2500\u2500 mobile presentation (.vela-sd-mobile on the scrim; structural sizes are inline in open()) \u2500\u2500
|
|
28724
28799
|
The tab rail becomes a burger-opened overlay sidebar; the group TOC becomes a sticky
|
|
28725
28800
|
row of horizontally scrollable tabs; the instance strip scrolls instead of wrapping;
|
|
@@ -28768,6 +28843,8 @@ var SettingsDialog = class {
|
|
|
28768
28843
|
this.hostSections = [];
|
|
28769
28844
|
/** The timeline-mark groups (defined + named by marks) — one checkbox each on the Events tab. */
|
|
28770
28845
|
this.markGroups = [];
|
|
28846
|
+
/** A group's OWN switch (what its checkbox shows) — a child under an off parent keeps its own state. */
|
|
28847
|
+
this.markGroupOwnVisible = () => true;
|
|
28771
28848
|
this.markGroupVisible = () => true;
|
|
28772
28849
|
/** The Canvas → Theme row: current app theme + where a pick is raised. The row is a
|
|
28773
28850
|
* host callback, NOT a config patch — the app theme stays out of the persisted
|
|
@@ -28785,6 +28862,9 @@ var SettingsDialog = class {
|
|
|
28785
28862
|
this.activeSection = null;
|
|
28786
28863
|
/** Mobile chrome: fullscreen card, burger-opened section sidebar, TOC as top tabs. */
|
|
28787
28864
|
this.mobileLayout = false;
|
|
28865
|
+
/** Opens/closes the mobile section sidebar of the CURRENT build (the burger in the
|
|
28866
|
+
* shell header outlives pane rebuilds, so it reaches the rail through here). */
|
|
28867
|
+
this.toggleRail = null;
|
|
28788
28868
|
/** The visibility policy: setting ids hidden by the host (subtree semantics). */
|
|
28789
28869
|
this.hiddenSettings = /* @__PURE__ */ new Set();
|
|
28790
28870
|
if (getComputedStyle(container).position === "static") container.style.position = "relative";
|
|
@@ -28794,7 +28874,8 @@ var SettingsDialog = class {
|
|
|
28794
28874
|
this.hostSections = sections;
|
|
28795
28875
|
}
|
|
28796
28876
|
/** The timeline-mark groups and their current visibility — the Events tab's rows on next open. */
|
|
28797
|
-
setMarkGroups(groups, visible) {
|
|
28877
|
+
setMarkGroups(groups, visible, ownVisible = visible) {
|
|
28878
|
+
this.markGroupOwnVisible = ownVisible;
|
|
28798
28879
|
this.markGroups = groups;
|
|
28799
28880
|
this.markGroupVisible = visible;
|
|
28800
28881
|
}
|
|
@@ -28860,7 +28941,6 @@ var SettingsDialog = class {
|
|
|
28860
28941
|
this.onReset = onReset ?? null;
|
|
28861
28942
|
ensureControlStyles();
|
|
28862
28943
|
const mobile = this.mobileLayout;
|
|
28863
|
-
let toggleRail = null;
|
|
28864
28944
|
let burger;
|
|
28865
28945
|
if (mobile) {
|
|
28866
28946
|
burger = document.createElement("button");
|
|
@@ -28868,8 +28948,83 @@ var SettingsDialog = class {
|
|
|
28868
28948
|
burger.className = "vela-sd-burger";
|
|
28869
28949
|
burger.innerHTML = iconAt("burger", 16);
|
|
28870
28950
|
burger.title = "Sections";
|
|
28871
|
-
burger.addEventListener("click", () => toggleRail?.());
|
|
28951
|
+
burger.addEventListener("click", () => this.toggleRail?.());
|
|
28872
28952
|
}
|
|
28953
|
+
const ui = new Dialog({
|
|
28954
|
+
host: this.container,
|
|
28955
|
+
title: "Chart settings",
|
|
28956
|
+
// Non-modal: a live-edit dialog must leave the page interactive — a modal
|
|
28957
|
+
// machine locks pointer events on the whole body, killing the chart, the
|
|
28958
|
+
// legend, and the body-portaled popovers (color picker, select lists).
|
|
28959
|
+
modal: false,
|
|
28960
|
+
contained: true,
|
|
28961
|
+
align: "top",
|
|
28962
|
+
draggable: !mobile,
|
|
28963
|
+
flush: true,
|
|
28964
|
+
className: "vela-dialog--settings",
|
|
28965
|
+
headerStart: burger,
|
|
28966
|
+
closeOnBackdrop: true,
|
|
28967
|
+
footer: (foot) => {
|
|
28968
|
+
foot.style.cssText = `padding:10px 14px;display:flex;align-items:center;justify-content:flex-start;gap:8px;`;
|
|
28969
|
+
const resetBtn = document.createElement("button");
|
|
28970
|
+
resetBtn.type = "button";
|
|
28971
|
+
resetBtn.textContent = "Reset defaults";
|
|
28972
|
+
resetBtn.className = "vela-sd-btn";
|
|
28973
|
+
resetBtn.addEventListener("click", () => this.onReset?.());
|
|
28974
|
+
foot.appendChild(resetBtn);
|
|
28975
|
+
},
|
|
28976
|
+
// A close signal may only close ITS OWN dialog: the machine reports the exit
|
|
28977
|
+
// asynchronously, so a close-then-reopen in one tick would otherwise see the
|
|
28978
|
+
// old instance's signal tear down the freshly opened one.
|
|
28979
|
+
onOpenChange: (open2) => {
|
|
28980
|
+
if (!open2 && this.ui === ui) this.close();
|
|
28981
|
+
}
|
|
28982
|
+
});
|
|
28983
|
+
if (mobile) ui.positioner.classList.add("vela-sd-mobile");
|
|
28984
|
+
ui.positioner.style.paddingTop = mobile ? "0" : "8vh";
|
|
28985
|
+
this.root = ui.positioner;
|
|
28986
|
+
this.ui = ui;
|
|
28987
|
+
const panes = this.buildContent(ui, config, section, mobile);
|
|
28988
|
+
ui.show();
|
|
28989
|
+
this.layoutPanes(panes);
|
|
28990
|
+
}
|
|
28991
|
+
/**
|
|
28992
|
+
* Re-seed every control of an OPEN dialog from `config`, in place: the shell stays
|
|
28993
|
+
* (no close/open transition), only the tab rail and panes rebuild, landing back on
|
|
28994
|
+
* the current tab. The reset path — the restored values must show without the
|
|
28995
|
+
* dialog re-entering. No-op while closed.
|
|
28996
|
+
*/
|
|
28997
|
+
refresh(config) {
|
|
28998
|
+
const ui = this.ui;
|
|
28999
|
+
if (!ui) return;
|
|
29000
|
+
closeOpenPopovers();
|
|
29001
|
+
closeWidthPopover();
|
|
29002
|
+
for (const dispose of this.hintTips) dispose();
|
|
29003
|
+
this.hintTips = [];
|
|
29004
|
+
this.config = config;
|
|
29005
|
+
ui.body.replaceChildren();
|
|
29006
|
+
this.layoutPanes(this.buildContent(ui, config, this.activeSection ?? void 0, this.mobileLayout));
|
|
29007
|
+
}
|
|
29008
|
+
/** Structured chart-type panes (instance strip / group TOC) own their layout and
|
|
29009
|
+
* tag their rows hosts instead; each host gets its own field grid. Runs on a SHOWN
|
|
29010
|
+
* dialog — the grids measure their labels. */
|
|
29011
|
+
layoutPanes(panes) {
|
|
29012
|
+
for (const el of panes) {
|
|
29013
|
+
const hosts = [...el.querySelectorAll("[data-sd-rows-host]")];
|
|
29014
|
+
if (hosts.length === 0) {
|
|
29015
|
+
this.layoutSettingsGrids(el);
|
|
29016
|
+
continue;
|
|
29017
|
+
}
|
|
29018
|
+
for (const h of hosts) this.layoutSettingsGrids(h);
|
|
29019
|
+
}
|
|
29020
|
+
}
|
|
29021
|
+
/**
|
|
29022
|
+
* Build the tab rail + one pane per section into `ui.body` (the linear `body` of
|
|
29023
|
+
* section markers and rows is split afterwards), select `section` (the active
|
|
29024
|
+
* style's own tab when none is asked for), and return the pane elements for
|
|
29025
|
+
* {@link layoutPanes}.
|
|
29026
|
+
*/
|
|
29027
|
+
buildContent(ui, config, section, mobile) {
|
|
28873
29028
|
const body = document.createElement("div");
|
|
28874
29029
|
body.style.cssText = "display:flex;flex-direction:column;gap:0;";
|
|
28875
29030
|
const sid = (el, id) => {
|
|
@@ -29073,9 +29228,28 @@ var SettingsDialog = class {
|
|
|
29073
29228
|
if (this.markGroups.length > 0) {
|
|
29074
29229
|
body.append(sid(this.section("Events"), MARKS_SETTINGS_ID));
|
|
29075
29230
|
body.append(sid(this.sectionTitle("Visible events"), MARKS_GROUPS_SETTINGS_ID));
|
|
29076
|
-
|
|
29077
|
-
|
|
29231
|
+
const rowsById = /* @__PURE__ */ new Map();
|
|
29232
|
+
const rows = markGroupRows(this.markGroups);
|
|
29233
|
+
const refreshDimming = () => {
|
|
29234
|
+
for (const { group } of rows) {
|
|
29235
|
+
const el = rowsById.get(group.id);
|
|
29236
|
+
if (!el || group.parent === void 0) continue;
|
|
29237
|
+
el.classList.toggle("vela-sd-soft", !this.markGroupVisible(group.parent));
|
|
29238
|
+
}
|
|
29239
|
+
};
|
|
29240
|
+
for (const { group: g, depth } of rows) {
|
|
29241
|
+
const row = this.boolRow(g.label, this.markGroupOwnVisible(g.id), (v) => {
|
|
29242
|
+
this.emit({ marks: { groups: { [g.id]: v } } });
|
|
29243
|
+
refreshDimming();
|
|
29244
|
+
});
|
|
29245
|
+
if (depth > 0) {
|
|
29246
|
+
row.classList.add("vela-sd-nested");
|
|
29247
|
+
row.style.setProperty("--vela-sd-depth", String(depth));
|
|
29248
|
+
}
|
|
29249
|
+
rowsById.set(g.id, row);
|
|
29250
|
+
body.append(sid(row, markGroupSettingsId(g.id)));
|
|
29078
29251
|
}
|
|
29252
|
+
refreshDimming();
|
|
29079
29253
|
}
|
|
29080
29254
|
renderChartTypeSections("end");
|
|
29081
29255
|
renderHostSections("end");
|
|
@@ -29103,8 +29277,8 @@ var SettingsDialog = class {
|
|
|
29103
29277
|
if (mobile) {
|
|
29104
29278
|
railScrim = document.createElement("div");
|
|
29105
29279
|
railScrim.className = "vela-sd-railscrim";
|
|
29106
|
-
railScrim.addEventListener("click", () => toggleRail?.());
|
|
29107
|
-
toggleRail = (open2) => {
|
|
29280
|
+
railScrim.addEventListener("click", () => this.toggleRail?.());
|
|
29281
|
+
this.toggleRail = (open2) => {
|
|
29108
29282
|
const on = open2 ?? !rail.classList.contains("open");
|
|
29109
29283
|
rail.classList.toggle("open", on);
|
|
29110
29284
|
railScrim?.classList.toggle("open", on);
|
|
@@ -29144,35 +29318,6 @@ var SettingsDialog = class {
|
|
|
29144
29318
|
});
|
|
29145
29319
|
if (hidActive) activate(0);
|
|
29146
29320
|
};
|
|
29147
|
-
const ui = new Dialog({
|
|
29148
|
-
host: this.container,
|
|
29149
|
-
title: "Chart settings",
|
|
29150
|
-
// Non-modal: a live-edit dialog must leave the page interactive — a modal
|
|
29151
|
-
// machine locks pointer events on the whole body, killing the chart, the
|
|
29152
|
-
// legend, and the body-portaled popovers (color picker, select lists).
|
|
29153
|
-
modal: false,
|
|
29154
|
-
contained: true,
|
|
29155
|
-
align: "top",
|
|
29156
|
-
draggable: !mobile,
|
|
29157
|
-
flush: true,
|
|
29158
|
-
className: "vela-dialog--settings",
|
|
29159
|
-
headerStart: burger,
|
|
29160
|
-
closeOnBackdrop: true,
|
|
29161
|
-
footer: (foot) => {
|
|
29162
|
-
foot.style.cssText = `padding:10px 14px;display:flex;align-items:center;justify-content:flex-start;gap:8px;`;
|
|
29163
|
-
const resetBtn = document.createElement("button");
|
|
29164
|
-
resetBtn.type = "button";
|
|
29165
|
-
resetBtn.textContent = "Reset defaults";
|
|
29166
|
-
resetBtn.className = "vela-sd-btn";
|
|
29167
|
-
resetBtn.addEventListener("click", () => this.onReset?.());
|
|
29168
|
-
foot.appendChild(resetBtn);
|
|
29169
|
-
},
|
|
29170
|
-
onOpenChange: (open2) => {
|
|
29171
|
-
if (!open2) this.close();
|
|
29172
|
-
}
|
|
29173
|
-
});
|
|
29174
|
-
if (mobile) ui.positioner.classList.add("vela-sd-mobile");
|
|
29175
|
-
ui.positioner.style.paddingTop = mobile ? "0" : "8vh";
|
|
29176
29321
|
const activate = (idx) => {
|
|
29177
29322
|
panes.forEach((p, i) => {
|
|
29178
29323
|
p.el.style.display = i === idx ? "block" : "none";
|
|
@@ -29181,7 +29326,7 @@ var SettingsDialog = class {
|
|
|
29181
29326
|
this.activeSection = panes[idx]?.title ?? null;
|
|
29182
29327
|
if (mobile) {
|
|
29183
29328
|
ui.titleEl.textContent = panes[idx]?.title ?? "Chart settings";
|
|
29184
|
-
toggleRail?.(false);
|
|
29329
|
+
this.toggleRail?.(false);
|
|
29185
29330
|
}
|
|
29186
29331
|
};
|
|
29187
29332
|
panes.forEach((p, i) => {
|
|
@@ -29196,17 +29341,7 @@ var SettingsDialog = class {
|
|
|
29196
29341
|
shell.append(rail, paneHost);
|
|
29197
29342
|
if (railScrim) shell.append(railScrim);
|
|
29198
29343
|
ui.body.appendChild(shell);
|
|
29199
|
-
|
|
29200
|
-
this.ui = ui;
|
|
29201
|
-
ui.show();
|
|
29202
|
-
for (const p of panes) {
|
|
29203
|
-
const hosts = [...p.el.querySelectorAll("[data-sd-rows-host]")];
|
|
29204
|
-
if (hosts.length === 0) {
|
|
29205
|
-
this.layoutSettingsGrids(p.el);
|
|
29206
|
-
continue;
|
|
29207
|
-
}
|
|
29208
|
-
for (const h of hosts) this.layoutSettingsGrids(h);
|
|
29209
|
-
}
|
|
29344
|
+
return panes.map((p) => p.el);
|
|
29210
29345
|
}
|
|
29211
29346
|
close() {
|
|
29212
29347
|
closeOpenPopovers();
|
|
@@ -29214,6 +29349,7 @@ var SettingsDialog = class {
|
|
|
29214
29349
|
const ui = this.ui;
|
|
29215
29350
|
this.ui = null;
|
|
29216
29351
|
this.root = null;
|
|
29352
|
+
this.toggleRail = null;
|
|
29217
29353
|
this.tabs = [];
|
|
29218
29354
|
for (const dispose of this.hintTips) dispose();
|
|
29219
29355
|
this.hintTips = [];
|
|
@@ -36532,7 +36668,11 @@ var NativeRenderer = class {
|
|
|
36532
36668
|
}
|
|
36533
36669
|
this.settingsDialog.setTheme(this.theme);
|
|
36534
36670
|
this.settingsDialog.setHostSections(this.hostSettingsSections);
|
|
36535
|
-
this.settingsDialog.setMarkGroups(
|
|
36671
|
+
this.settingsDialog.setMarkGroups(
|
|
36672
|
+
this.markGroupsForEventsTab(),
|
|
36673
|
+
(id) => markGroupVisible2(this.scene.marks, id, this.scene.markGroups),
|
|
36674
|
+
(id) => markGroupOwnVisible(this.scene.marks.groups, id, this.scene.markGroups)
|
|
36675
|
+
);
|
|
36536
36676
|
this.settingsDialog.setHiddenSettings(this.hiddenSettings);
|
|
36537
36677
|
this.syncThemeControl();
|
|
36538
36678
|
this.settingsDialog.toggle(
|
|
@@ -36540,13 +36680,24 @@ var NativeRenderer = class {
|
|
|
36540
36680
|
(patch) => this.applyConfig(patch),
|
|
36541
36681
|
(json) => this.applyConfig(json),
|
|
36542
36682
|
() => {
|
|
36543
|
-
if (this.factoryConfig) this.applyConfig(
|
|
36544
|
-
this.settingsDialog?.
|
|
36545
|
-
this.openSettingsDialog();
|
|
36683
|
+
if (this.factoryConfig) this.applyConfig(this.factoryResetDocument(this.factoryConfig));
|
|
36684
|
+
this.settingsDialog?.refresh(this.getConfig());
|
|
36546
36685
|
},
|
|
36547
36686
|
section
|
|
36548
36687
|
);
|
|
36549
36688
|
}
|
|
36689
|
+
/**
|
|
36690
|
+
* The document "Reset defaults" applies: every setting back to its first-run value,
|
|
36691
|
+
* with two things that are NOT settings held or resolved here — the price style
|
|
36692
|
+
* stays the one the user is looking at, and the timeline-mark groups (an additive
|
|
36693
|
+
* merge, like the type bags) are named back to their host-declared visibility.
|
|
36694
|
+
*/
|
|
36695
|
+
factoryResetDocument(factory) {
|
|
36696
|
+
const doc = factoryResetConfig(factory, this.scene.priceStyle);
|
|
36697
|
+
const groups = { ...doc.marks.groups };
|
|
36698
|
+
for (const g of this.markGroupsInUse()) groups[g.id] = g.visible !== false;
|
|
36699
|
+
return { ...doc, marks: { ...doc.marks, groups } };
|
|
36700
|
+
}
|
|
36550
36701
|
/** Close the in-chart dialogs (indicator settings + chart-settings gear). No-op when none are open. */
|
|
36551
36702
|
closeDialogs() {
|
|
36552
36703
|
this.inputsUI?.closeOpenDialog();
|
|
@@ -37609,6 +37760,15 @@ var NativeRenderer = class {
|
|
|
37609
37760
|
markGroupsInUse() {
|
|
37610
37761
|
return effectiveMarkGroups(this.scene.timelineMarks, this.scene.markGroups);
|
|
37611
37762
|
}
|
|
37763
|
+
/**
|
|
37764
|
+
* The groups as the Events tab lists them: nested only under a DEFINED parent. The
|
|
37765
|
+
* painter's visibility chain resolves parents against the defined groups alone, so a
|
|
37766
|
+
* parent that marks merely name must not nest (and dim) a child the painter still shows.
|
|
37767
|
+
*/
|
|
37768
|
+
markGroupsForEventsTab() {
|
|
37769
|
+
const defined = new Set(this.scene.markGroups.map((g) => g.id));
|
|
37770
|
+
return this.markGroupsInUse().map((g) => g.parent !== void 0 && !defined.has(g.parent) ? { ...g, parent: void 0 } : g);
|
|
37771
|
+
}
|
|
37612
37772
|
onViewportChange(cb) {
|
|
37613
37773
|
this.viewportCbs.add(cb);
|
|
37614
37774
|
return () => this.viewportCbs.delete(cb);
|
|
@@ -43501,6 +43661,11 @@ var ChartCell = class {
|
|
|
43501
43661
|
if (typeof zone === "string" && normalizeTimezone(zone) !== normalizeTimezone(this.deps.timezone())) {
|
|
43502
43662
|
this.deps.setTimezone(normalizeTimezone(zone));
|
|
43503
43663
|
}
|
|
43664
|
+
const style = this.priceStyle;
|
|
43665
|
+
if (style !== (this.state.priceStyle ?? "candles")) {
|
|
43666
|
+
this.state.priceStyle = style;
|
|
43667
|
+
this.deps.onPriceStyleChanged(this.id);
|
|
43668
|
+
}
|
|
43504
43669
|
this.syncStatuslineColors();
|
|
43505
43670
|
this.syncPlotOverlayTokens();
|
|
43506
43671
|
});
|
package/dist/workspace.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-
|
|
2
|
-
import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-
|
|
3
|
-
export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-
|
|
1
|
+
import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-DNBoMKkX.cjs';
|
|
2
|
+
import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-gA__yaog.cjs';
|
|
3
|
+
export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-gA__yaog.cjs';
|
|
4
4
|
import { K as KeymapManager } from './keymap-CGOz5F5f.cjs';
|
|
5
|
-
import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-
|
|
6
|
-
import { M as MarketDataFeed } from './DataProvider-
|
|
5
|
+
import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-DYtiRtES.cjs';
|
|
6
|
+
import { M as MarketDataFeed } from './DataProvider-Dut6lXGM.cjs';
|
|
7
7
|
|
|
8
8
|
/** The cells that follow `originId` under `setting` — PURE (never includes the origin). */
|
|
9
9
|
declare function syncTargets(originId: string, setting: SyncSetting | undefined, cellIds: readonly string[]): string[];
|
package/dist/workspace.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-
|
|
2
|
-
import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-
|
|
3
|
-
export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-
|
|
1
|
+
import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-DNBoMKkX.js';
|
|
2
|
+
import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-DypGXjtr.js';
|
|
3
|
+
export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-DypGXjtr.js';
|
|
4
4
|
import { K as KeymapManager } from './keymap-CGOz5F5f.js';
|
|
5
|
-
import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-
|
|
6
|
-
import { M as MarketDataFeed } from './DataProvider-
|
|
5
|
+
import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-CEkgJKTU.js';
|
|
6
|
+
import { M as MarketDataFeed } from './DataProvider-DLeFs1gE.js';
|
|
7
7
|
|
|
8
8
|
/** The cells that follow `originId` under `setting` — PURE (never includes the origin). */
|
|
9
9
|
declare function syncTargets(originId: string, setting: SyncSetting | undefined, cellIds: readonly string[]): string[];
|
package/dist/workspace.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ChartCell, GRID_PICKER_MAX, VelaWorkspace, activeAfterLayout, decodeState, encodeState, ensureLayout, evenTracks, gridStyles, layoutDefinition, layoutForGrid, layoutShape, layouts, memoryStorageAdapter, rangesWithin, registerBuiltinLayouts, registerLayout, resizeTracks, sanitizeState, syncTargets, trackOffsets, unregisterLayout } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { ChartCell, GRID_PICKER_MAX, VelaWorkspace, activeAfterLayout, decodeState, encodeState, ensureLayout, evenTracks, gridStyles, layoutDefinition, layoutForGrid, layoutShape, layouts, memoryStorageAdapter, rangesWithin, registerBuiltinLayouts, registerLayout, resizeTracks, sanitizeState, syncTargets, trackOffsets, unregisterLayout } from './chunk-MNG5XPLV.js';
|
|
2
|
+
import './chunk-MCLI6B3S.js';
|
|
3
3
|
import './chunk-BFA32GOU.js';
|
|
4
4
|
import './chunk-ZADTVRUO.js';
|
|
5
5
|
import './chunk-BKHSQ4YM.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luxalgo/vela",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "Open-source charting library with a native high-performance renderer, drawing tools, pluggable chart types and pluggable scripting engines.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://luxalgo.com/vela",
|