@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/widget.cjs
CHANGED
|
@@ -5115,6 +5115,17 @@ function hasOwnCandlePaint(style) {
|
|
|
5115
5115
|
for (const t of chartTypes()) if (t.id === style) return (t.basePainting ?? "candles") === "candles";
|
|
5116
5116
|
return false;
|
|
5117
5117
|
}
|
|
5118
|
+
var CANDLE_OVERRIDE_KEYS = [
|
|
5119
|
+
"candleUpColor",
|
|
5120
|
+
"candleDownColor",
|
|
5121
|
+
"candleBodyVisible",
|
|
5122
|
+
"candleBorderVisible",
|
|
5123
|
+
"candleBorderUpColor",
|
|
5124
|
+
"candleBorderDownColor",
|
|
5125
|
+
"candleWickVisible",
|
|
5126
|
+
"candleWickUpColor",
|
|
5127
|
+
"candleWickDownColor"
|
|
5128
|
+
];
|
|
5118
5129
|
function candleOverrideFor(style, bags) {
|
|
5119
5130
|
if (!hasOwnCandlePaint(style)) return null;
|
|
5120
5131
|
const bag = bags[style] ?? {};
|
|
@@ -5186,7 +5197,7 @@ function clampLevel(v) {
|
|
|
5186
5197
|
function clampSpacing(v) {
|
|
5187
5198
|
return v < 0.1 ? 0.1 : v > 10 ? 10 : v;
|
|
5188
5199
|
}
|
|
5189
|
-
function factoryResetConfig(factory) {
|
|
5200
|
+
function factoryResetConfig(factory, priceStyle = factory.series.style) {
|
|
5190
5201
|
const bag = {};
|
|
5191
5202
|
for (const t of chartTypes()) {
|
|
5192
5203
|
const section = t.settings;
|
|
@@ -5208,10 +5219,16 @@ function factoryResetConfig(factory) {
|
|
|
5208
5219
|
if (!section.instances) addRows(section.rows);
|
|
5209
5220
|
bag[t.id] = defaults2;
|
|
5210
5221
|
}
|
|
5222
|
+
for (const t of chartTypes()) {
|
|
5223
|
+
if (!hasOwnCandlePaint(t.id)) continue;
|
|
5224
|
+
const defaults2 = bag[t.id] ?? {};
|
|
5225
|
+
for (const key of CANDLE_OVERRIDE_KEYS) defaults2[key] = null;
|
|
5226
|
+
bag[t.id] = defaults2;
|
|
5227
|
+
}
|
|
5211
5228
|
for (const [typeId, vals] of Object.entries(factory.chartTypes)) {
|
|
5212
5229
|
bag[typeId] = { ...bag[typeId] ?? {}, ...vals };
|
|
5213
5230
|
}
|
|
5214
|
-
return { ...factory, chartTypes: bag };
|
|
5231
|
+
return { ...factory, chartTypes: bag, series: { ...factory.series, style: priceStyle } };
|
|
5215
5232
|
}
|
|
5216
5233
|
function mergeConfig(base, patch) {
|
|
5217
5234
|
const p = asObject(patch);
|
|
@@ -18653,6 +18670,42 @@ function presetToRange(preset, bars) {
|
|
|
18653
18670
|
return { from: Math.max(first, from), to: last };
|
|
18654
18671
|
}
|
|
18655
18672
|
|
|
18673
|
+
// src/core/marks/visibility.ts
|
|
18674
|
+
function markGroupOwnVisible(choices, groupId, groups) {
|
|
18675
|
+
const chosen = choices[groupId];
|
|
18676
|
+
if (typeof chosen === "boolean") return chosen;
|
|
18677
|
+
return groups.find((g) => g.id === groupId)?.visible !== false;
|
|
18678
|
+
}
|
|
18679
|
+
function markGroupVisible(choices, groupId, groups) {
|
|
18680
|
+
if (groupId === void 0) return true;
|
|
18681
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18682
|
+
let id = groupId;
|
|
18683
|
+
while (id !== void 0 && !seen.has(id)) {
|
|
18684
|
+
seen.add(id);
|
|
18685
|
+
if (!markGroupOwnVisible(choices, id, groups)) return false;
|
|
18686
|
+
const parent = groups.find((g) => g.id === id)?.parent;
|
|
18687
|
+
id = parent !== void 0 && groups.some((g) => g.id === parent) ? parent : void 0;
|
|
18688
|
+
}
|
|
18689
|
+
return true;
|
|
18690
|
+
}
|
|
18691
|
+
function markGroupRows(groups) {
|
|
18692
|
+
const ids = new Set(groups.map((g) => g.id));
|
|
18693
|
+
const out = [];
|
|
18694
|
+
const placed = /* @__PURE__ */ new Set();
|
|
18695
|
+
const place = (group, depth) => {
|
|
18696
|
+
if (placed.has(group.id)) return;
|
|
18697
|
+
placed.add(group.id);
|
|
18698
|
+
out.push({ group, depth });
|
|
18699
|
+
for (const child of groups) if (child.parent === group.id && child.id !== group.id) place(child, depth + 1);
|
|
18700
|
+
};
|
|
18701
|
+
for (const g of groups) {
|
|
18702
|
+
const parentKnown = g.parent !== void 0 && ids.has(g.parent) && g.parent !== g.id;
|
|
18703
|
+
if (!parentKnown) place(g, 0);
|
|
18704
|
+
}
|
|
18705
|
+
for (const g of groups) place(g, 0);
|
|
18706
|
+
return out;
|
|
18707
|
+
}
|
|
18708
|
+
|
|
18656
18709
|
// src/core/marks/MarksController.ts
|
|
18657
18710
|
var MarksController = class {
|
|
18658
18711
|
constructor(renderer, events) {
|
|
@@ -18697,6 +18750,7 @@ var MarksController = class {
|
|
|
18697
18750
|
defineGroup(group) {
|
|
18698
18751
|
if (!group || typeof group.id !== "string" || group.id.length === 0) throw new Error("[vela] marks.defineGroup: `id` must be a non-empty string");
|
|
18699
18752
|
if (typeof group.label !== "string") throw new Error(`[vela] marks.defineGroup: group "${group.id}" needs a string \`label\``);
|
|
18753
|
+
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`);
|
|
18700
18754
|
this.groups.set(group.id, { ...group });
|
|
18701
18755
|
this.sync();
|
|
18702
18756
|
}
|
|
@@ -18716,12 +18770,16 @@ var MarksController = class {
|
|
|
18716
18770
|
}
|
|
18717
18771
|
this.renderer.applyFeature("marks", { groups: { [id]: visible } });
|
|
18718
18772
|
}
|
|
18719
|
-
/**
|
|
18773
|
+
/**
|
|
18774
|
+
* A group's effective visibility: its own switch — the user's (persisted) choice, else
|
|
18775
|
+
* the declared default, else visible — AND every ancestor's, so a child under a
|
|
18776
|
+
* switched-off parent reads hidden whatever its own choice says.
|
|
18777
|
+
*/
|
|
18720
18778
|
isGroupVisible(id) {
|
|
18721
18779
|
const state = this.renderer.readFeature("marks");
|
|
18722
|
-
const
|
|
18723
|
-
if (typeof
|
|
18724
|
-
return this.groups.
|
|
18780
|
+
const groups = {};
|
|
18781
|
+
for (const [gid, v] of Object.entries(state?.groups ?? {})) if (typeof v === "boolean") groups[gid] = v;
|
|
18782
|
+
return markGroupVisible(groups, id, [...this.groups.values()]);
|
|
18725
18783
|
}
|
|
18726
18784
|
destroy() {
|
|
18727
18785
|
for (const unsub of this.subs) unsub();
|
|
@@ -25710,11 +25768,8 @@ function mergeMarksState(base, patch) {
|
|
|
25710
25768
|
for (const [id, v] of Object.entries(g)) if (typeof v === "boolean") groups[id] = v;
|
|
25711
25769
|
return { visible: typeof p.visible === "boolean" ? p.visible : base.visible, groups };
|
|
25712
25770
|
}
|
|
25713
|
-
function
|
|
25714
|
-
|
|
25715
|
-
const chosen = state.groups[groupId];
|
|
25716
|
-
if (typeof chosen === "boolean") return chosen;
|
|
25717
|
-
return groups.find((g) => g.id === groupId)?.visible !== false;
|
|
25771
|
+
function markGroupVisible2(state, groupId, groups) {
|
|
25772
|
+
return markGroupVisible(state.groups, groupId, groups);
|
|
25718
25773
|
}
|
|
25719
25774
|
|
|
25720
25775
|
// src/renderers/native/core/SceneGraph.ts
|
|
@@ -27890,13 +27945,29 @@ function paintMarkLane(ctx, layout, deps) {
|
|
|
27890
27945
|
const img = deps.icons.get(mark.glyph.icon, ink, symbolPx, deps.dpr);
|
|
27891
27946
|
if (img) ctx.drawImage(img, center.x - symbolPx / 2, center.y - symbolPx / 2, symbolPx, symbolPx);
|
|
27892
27947
|
} else if (mark.glyph.letter) {
|
|
27948
|
+
const letter = mark.glyph.letter.slice(0, 2);
|
|
27893
27949
|
ctx.fillStyle = ink;
|
|
27894
|
-
|
|
27895
|
-
ctx.
|
|
27950
|
+
let px = letterFontPx(size, letter);
|
|
27951
|
+
ctx.font = `600 ${px}px ${deps.fontFamily}`;
|
|
27952
|
+
if (letter.length > 1) {
|
|
27953
|
+
px = fitLetterPx(px, ctx.measureText(letter).width, symbolInnerWidth(shape, size));
|
|
27954
|
+
ctx.font = `600 ${px}px ${deps.fontFamily}`;
|
|
27955
|
+
}
|
|
27956
|
+
ctx.fillText(letter, center.x, center.y + 0.5);
|
|
27896
27957
|
}
|
|
27897
27958
|
}
|
|
27898
27959
|
ctx.restore();
|
|
27899
27960
|
}
|
|
27961
|
+
function letterFontPx(size, letter) {
|
|
27962
|
+
return Math.round(size * (letter.length > 1 ? 0.38 : 0.58));
|
|
27963
|
+
}
|
|
27964
|
+
function symbolInnerWidth(shape, size) {
|
|
27965
|
+
return (shape === "pin" ? size * 0.82 : size) - 3;
|
|
27966
|
+
}
|
|
27967
|
+
function fitLetterPx(px, width, inner) {
|
|
27968
|
+
if (!(width > inner) || !(width > 0)) return px;
|
|
27969
|
+
return Math.max(4, Math.floor(px * inner / width));
|
|
27970
|
+
}
|
|
27900
27971
|
function traceShape(ctx, shape, x, y, size) {
|
|
27901
27972
|
const r = size / 2;
|
|
27902
27973
|
ctx.beginPath();
|
|
@@ -28098,7 +28169,7 @@ var ChromeRenderer = class {
|
|
|
28098
28169
|
this.markLayout = layoutMarkLane({
|
|
28099
28170
|
marks: scene.timelineMarks,
|
|
28100
28171
|
groups: scene.markGroups,
|
|
28101
|
-
hidden: (groupId) => !
|
|
28172
|
+
hidden: (groupId) => !markGroupVisible2(scene.marks, groupId, scene.markGroups),
|
|
28102
28173
|
barTimes: this.barTimes(scene),
|
|
28103
28174
|
intervalMs: coords.barInterval,
|
|
28104
28175
|
xOf: (bar) => coords.logicalToX(bar),
|
|
@@ -28788,6 +28859,10 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
28788
28859
|
muted and non-interactive. Applied to each row's children so it survives display:contents;
|
|
28789
28860
|
!important beats the inline opacity on labels. */
|
|
28790
28861
|
.vela-sd-soft>*{opacity:0.4 !important;pointer-events:none !important;}
|
|
28862
|
+
/* A mark group nested under a parent group on the Events tab: indented one step per level
|
|
28863
|
+
(--vela-sd-depth). The indent rides the first child (the switch) as a MARGIN \u2014 padding
|
|
28864
|
+
would push the switch's own tick out of its box. */
|
|
28865
|
+
.vela-sd-nested>*:first-child{margin-left:calc(var(--vela-sd-depth,1)*24px);}
|
|
28791
28866
|
/* \u2500\u2500 mobile presentation (.vela-sd-mobile on the scrim; structural sizes are inline in open()) \u2500\u2500
|
|
28792
28867
|
The tab rail becomes a burger-opened overlay sidebar; the group TOC becomes a sticky
|
|
28793
28868
|
row of horizontally scrollable tabs; the instance strip scrolls instead of wrapping;
|
|
@@ -28836,6 +28911,8 @@ var SettingsDialog = class {
|
|
|
28836
28911
|
this.hostSections = [];
|
|
28837
28912
|
/** The timeline-mark groups (defined + named by marks) — one checkbox each on the Events tab. */
|
|
28838
28913
|
this.markGroups = [];
|
|
28914
|
+
/** A group's OWN switch (what its checkbox shows) — a child under an off parent keeps its own state. */
|
|
28915
|
+
this.markGroupOwnVisible = () => true;
|
|
28839
28916
|
this.markGroupVisible = () => true;
|
|
28840
28917
|
/** The Canvas → Theme row: current app theme + where a pick is raised. The row is a
|
|
28841
28918
|
* host callback, NOT a config patch — the app theme stays out of the persisted
|
|
@@ -28853,6 +28930,9 @@ var SettingsDialog = class {
|
|
|
28853
28930
|
this.activeSection = null;
|
|
28854
28931
|
/** Mobile chrome: fullscreen card, burger-opened section sidebar, TOC as top tabs. */
|
|
28855
28932
|
this.mobileLayout = false;
|
|
28933
|
+
/** Opens/closes the mobile section sidebar of the CURRENT build (the burger in the
|
|
28934
|
+
* shell header outlives pane rebuilds, so it reaches the rail through here). */
|
|
28935
|
+
this.toggleRail = null;
|
|
28856
28936
|
/** The visibility policy: setting ids hidden by the host (subtree semantics). */
|
|
28857
28937
|
this.hiddenSettings = /* @__PURE__ */ new Set();
|
|
28858
28938
|
if (getComputedStyle(container).position === "static") container.style.position = "relative";
|
|
@@ -28862,7 +28942,8 @@ var SettingsDialog = class {
|
|
|
28862
28942
|
this.hostSections = sections;
|
|
28863
28943
|
}
|
|
28864
28944
|
/** The timeline-mark groups and their current visibility — the Events tab's rows on next open. */
|
|
28865
|
-
setMarkGroups(groups, visible) {
|
|
28945
|
+
setMarkGroups(groups, visible, ownVisible = visible) {
|
|
28946
|
+
this.markGroupOwnVisible = ownVisible;
|
|
28866
28947
|
this.markGroups = groups;
|
|
28867
28948
|
this.markGroupVisible = visible;
|
|
28868
28949
|
}
|
|
@@ -28928,7 +29009,6 @@ var SettingsDialog = class {
|
|
|
28928
29009
|
this.onReset = onReset ?? null;
|
|
28929
29010
|
ensureControlStyles();
|
|
28930
29011
|
const mobile = this.mobileLayout;
|
|
28931
|
-
let toggleRail = null;
|
|
28932
29012
|
let burger;
|
|
28933
29013
|
if (mobile) {
|
|
28934
29014
|
burger = document.createElement("button");
|
|
@@ -28936,8 +29016,83 @@ var SettingsDialog = class {
|
|
|
28936
29016
|
burger.className = "vela-sd-burger";
|
|
28937
29017
|
burger.innerHTML = iconAt("burger", 16);
|
|
28938
29018
|
burger.title = "Sections";
|
|
28939
|
-
burger.addEventListener("click", () => toggleRail?.());
|
|
29019
|
+
burger.addEventListener("click", () => this.toggleRail?.());
|
|
28940
29020
|
}
|
|
29021
|
+
const ui = new Dialog({
|
|
29022
|
+
host: this.container,
|
|
29023
|
+
title: "Chart settings",
|
|
29024
|
+
// Non-modal: a live-edit dialog must leave the page interactive — a modal
|
|
29025
|
+
// machine locks pointer events on the whole body, killing the chart, the
|
|
29026
|
+
// legend, and the body-portaled popovers (color picker, select lists).
|
|
29027
|
+
modal: false,
|
|
29028
|
+
contained: true,
|
|
29029
|
+
align: "top",
|
|
29030
|
+
draggable: !mobile,
|
|
29031
|
+
flush: true,
|
|
29032
|
+
className: "vela-dialog--settings",
|
|
29033
|
+
headerStart: burger,
|
|
29034
|
+
closeOnBackdrop: true,
|
|
29035
|
+
footer: (foot) => {
|
|
29036
|
+
foot.style.cssText = `padding:10px 14px;display:flex;align-items:center;justify-content:flex-start;gap:8px;`;
|
|
29037
|
+
const resetBtn = document.createElement("button");
|
|
29038
|
+
resetBtn.type = "button";
|
|
29039
|
+
resetBtn.textContent = "Reset defaults";
|
|
29040
|
+
resetBtn.className = "vela-sd-btn";
|
|
29041
|
+
resetBtn.addEventListener("click", () => this.onReset?.());
|
|
29042
|
+
foot.appendChild(resetBtn);
|
|
29043
|
+
},
|
|
29044
|
+
// A close signal may only close ITS OWN dialog: the machine reports the exit
|
|
29045
|
+
// asynchronously, so a close-then-reopen in one tick would otherwise see the
|
|
29046
|
+
// old instance's signal tear down the freshly opened one.
|
|
29047
|
+
onOpenChange: (open2) => {
|
|
29048
|
+
if (!open2 && this.ui === ui) this.close();
|
|
29049
|
+
}
|
|
29050
|
+
});
|
|
29051
|
+
if (mobile) ui.positioner.classList.add("vela-sd-mobile");
|
|
29052
|
+
ui.positioner.style.paddingTop = mobile ? "0" : "8vh";
|
|
29053
|
+
this.root = ui.positioner;
|
|
29054
|
+
this.ui = ui;
|
|
29055
|
+
const panes = this.buildContent(ui, config, section, mobile);
|
|
29056
|
+
ui.show();
|
|
29057
|
+
this.layoutPanes(panes);
|
|
29058
|
+
}
|
|
29059
|
+
/**
|
|
29060
|
+
* Re-seed every control of an OPEN dialog from `config`, in place: the shell stays
|
|
29061
|
+
* (no close/open transition), only the tab rail and panes rebuild, landing back on
|
|
29062
|
+
* the current tab. The reset path — the restored values must show without the
|
|
29063
|
+
* dialog re-entering. No-op while closed.
|
|
29064
|
+
*/
|
|
29065
|
+
refresh(config) {
|
|
29066
|
+
const ui = this.ui;
|
|
29067
|
+
if (!ui) return;
|
|
29068
|
+
closeOpenPopovers();
|
|
29069
|
+
closeWidthPopover();
|
|
29070
|
+
for (const dispose of this.hintTips) dispose();
|
|
29071
|
+
this.hintTips = [];
|
|
29072
|
+
this.config = config;
|
|
29073
|
+
ui.body.replaceChildren();
|
|
29074
|
+
this.layoutPanes(this.buildContent(ui, config, this.activeSection ?? void 0, this.mobileLayout));
|
|
29075
|
+
}
|
|
29076
|
+
/** Structured chart-type panes (instance strip / group TOC) own their layout and
|
|
29077
|
+
* tag their rows hosts instead; each host gets its own field grid. Runs on a SHOWN
|
|
29078
|
+
* dialog — the grids measure their labels. */
|
|
29079
|
+
layoutPanes(panes) {
|
|
29080
|
+
for (const el of panes) {
|
|
29081
|
+
const hosts = [...el.querySelectorAll("[data-sd-rows-host]")];
|
|
29082
|
+
if (hosts.length === 0) {
|
|
29083
|
+
this.layoutSettingsGrids(el);
|
|
29084
|
+
continue;
|
|
29085
|
+
}
|
|
29086
|
+
for (const h of hosts) this.layoutSettingsGrids(h);
|
|
29087
|
+
}
|
|
29088
|
+
}
|
|
29089
|
+
/**
|
|
29090
|
+
* Build the tab rail + one pane per section into `ui.body` (the linear `body` of
|
|
29091
|
+
* section markers and rows is split afterwards), select `section` (the active
|
|
29092
|
+
* style's own tab when none is asked for), and return the pane elements for
|
|
29093
|
+
* {@link layoutPanes}.
|
|
29094
|
+
*/
|
|
29095
|
+
buildContent(ui, config, section, mobile) {
|
|
28941
29096
|
const body = document.createElement("div");
|
|
28942
29097
|
body.style.cssText = "display:flex;flex-direction:column;gap:0;";
|
|
28943
29098
|
const sid = (el, id) => {
|
|
@@ -29141,9 +29296,28 @@ var SettingsDialog = class {
|
|
|
29141
29296
|
if (this.markGroups.length > 0) {
|
|
29142
29297
|
body.append(sid(this.section("Events"), MARKS_SETTINGS_ID));
|
|
29143
29298
|
body.append(sid(this.sectionTitle("Visible events"), MARKS_GROUPS_SETTINGS_ID));
|
|
29144
|
-
|
|
29145
|
-
|
|
29299
|
+
const rowsById = /* @__PURE__ */ new Map();
|
|
29300
|
+
const rows = markGroupRows(this.markGroups);
|
|
29301
|
+
const refreshDimming = () => {
|
|
29302
|
+
for (const { group } of rows) {
|
|
29303
|
+
const el = rowsById.get(group.id);
|
|
29304
|
+
if (!el || group.parent === void 0) continue;
|
|
29305
|
+
el.classList.toggle("vela-sd-soft", !this.markGroupVisible(group.parent));
|
|
29306
|
+
}
|
|
29307
|
+
};
|
|
29308
|
+
for (const { group: g, depth } of rows) {
|
|
29309
|
+
const row = this.boolRow(g.label, this.markGroupOwnVisible(g.id), (v) => {
|
|
29310
|
+
this.emit({ marks: { groups: { [g.id]: v } } });
|
|
29311
|
+
refreshDimming();
|
|
29312
|
+
});
|
|
29313
|
+
if (depth > 0) {
|
|
29314
|
+
row.classList.add("vela-sd-nested");
|
|
29315
|
+
row.style.setProperty("--vela-sd-depth", String(depth));
|
|
29316
|
+
}
|
|
29317
|
+
rowsById.set(g.id, row);
|
|
29318
|
+
body.append(sid(row, markGroupSettingsId(g.id)));
|
|
29146
29319
|
}
|
|
29320
|
+
refreshDimming();
|
|
29147
29321
|
}
|
|
29148
29322
|
renderChartTypeSections("end");
|
|
29149
29323
|
renderHostSections("end");
|
|
@@ -29171,8 +29345,8 @@ var SettingsDialog = class {
|
|
|
29171
29345
|
if (mobile) {
|
|
29172
29346
|
railScrim = document.createElement("div");
|
|
29173
29347
|
railScrim.className = "vela-sd-railscrim";
|
|
29174
|
-
railScrim.addEventListener("click", () => toggleRail?.());
|
|
29175
|
-
toggleRail = (open2) => {
|
|
29348
|
+
railScrim.addEventListener("click", () => this.toggleRail?.());
|
|
29349
|
+
this.toggleRail = (open2) => {
|
|
29176
29350
|
const on = open2 ?? !rail.classList.contains("open");
|
|
29177
29351
|
rail.classList.toggle("open", on);
|
|
29178
29352
|
railScrim?.classList.toggle("open", on);
|
|
@@ -29212,35 +29386,6 @@ var SettingsDialog = class {
|
|
|
29212
29386
|
});
|
|
29213
29387
|
if (hidActive) activate(0);
|
|
29214
29388
|
};
|
|
29215
|
-
const ui = new Dialog({
|
|
29216
|
-
host: this.container,
|
|
29217
|
-
title: "Chart settings",
|
|
29218
|
-
// Non-modal: a live-edit dialog must leave the page interactive — a modal
|
|
29219
|
-
// machine locks pointer events on the whole body, killing the chart, the
|
|
29220
|
-
// legend, and the body-portaled popovers (color picker, select lists).
|
|
29221
|
-
modal: false,
|
|
29222
|
-
contained: true,
|
|
29223
|
-
align: "top",
|
|
29224
|
-
draggable: !mobile,
|
|
29225
|
-
flush: true,
|
|
29226
|
-
className: "vela-dialog--settings",
|
|
29227
|
-
headerStart: burger,
|
|
29228
|
-
closeOnBackdrop: true,
|
|
29229
|
-
footer: (foot) => {
|
|
29230
|
-
foot.style.cssText = `padding:10px 14px;display:flex;align-items:center;justify-content:flex-start;gap:8px;`;
|
|
29231
|
-
const resetBtn = document.createElement("button");
|
|
29232
|
-
resetBtn.type = "button";
|
|
29233
|
-
resetBtn.textContent = "Reset defaults";
|
|
29234
|
-
resetBtn.className = "vela-sd-btn";
|
|
29235
|
-
resetBtn.addEventListener("click", () => this.onReset?.());
|
|
29236
|
-
foot.appendChild(resetBtn);
|
|
29237
|
-
},
|
|
29238
|
-
onOpenChange: (open2) => {
|
|
29239
|
-
if (!open2) this.close();
|
|
29240
|
-
}
|
|
29241
|
-
});
|
|
29242
|
-
if (mobile) ui.positioner.classList.add("vela-sd-mobile");
|
|
29243
|
-
ui.positioner.style.paddingTop = mobile ? "0" : "8vh";
|
|
29244
29389
|
const activate = (idx) => {
|
|
29245
29390
|
panes.forEach((p, i) => {
|
|
29246
29391
|
p.el.style.display = i === idx ? "block" : "none";
|
|
@@ -29249,7 +29394,7 @@ var SettingsDialog = class {
|
|
|
29249
29394
|
this.activeSection = panes[idx]?.title ?? null;
|
|
29250
29395
|
if (mobile) {
|
|
29251
29396
|
ui.titleEl.textContent = panes[idx]?.title ?? "Chart settings";
|
|
29252
|
-
toggleRail?.(false);
|
|
29397
|
+
this.toggleRail?.(false);
|
|
29253
29398
|
}
|
|
29254
29399
|
};
|
|
29255
29400
|
panes.forEach((p, i) => {
|
|
@@ -29264,17 +29409,7 @@ var SettingsDialog = class {
|
|
|
29264
29409
|
shell.append(rail, paneHost);
|
|
29265
29410
|
if (railScrim) shell.append(railScrim);
|
|
29266
29411
|
ui.body.appendChild(shell);
|
|
29267
|
-
|
|
29268
|
-
this.ui = ui;
|
|
29269
|
-
ui.show();
|
|
29270
|
-
for (const p of panes) {
|
|
29271
|
-
const hosts = [...p.el.querySelectorAll("[data-sd-rows-host]")];
|
|
29272
|
-
if (hosts.length === 0) {
|
|
29273
|
-
this.layoutSettingsGrids(p.el);
|
|
29274
|
-
continue;
|
|
29275
|
-
}
|
|
29276
|
-
for (const h of hosts) this.layoutSettingsGrids(h);
|
|
29277
|
-
}
|
|
29412
|
+
return panes.map((p) => p.el);
|
|
29278
29413
|
}
|
|
29279
29414
|
close() {
|
|
29280
29415
|
closeOpenPopovers();
|
|
@@ -29282,6 +29417,7 @@ var SettingsDialog = class {
|
|
|
29282
29417
|
const ui = this.ui;
|
|
29283
29418
|
this.ui = null;
|
|
29284
29419
|
this.root = null;
|
|
29420
|
+
this.toggleRail = null;
|
|
29285
29421
|
this.tabs = [];
|
|
29286
29422
|
for (const dispose of this.hintTips) dispose();
|
|
29287
29423
|
this.hintTips = [];
|
|
@@ -36600,7 +36736,11 @@ var NativeRenderer = class {
|
|
|
36600
36736
|
}
|
|
36601
36737
|
this.settingsDialog.setTheme(this.theme);
|
|
36602
36738
|
this.settingsDialog.setHostSections(this.hostSettingsSections);
|
|
36603
|
-
this.settingsDialog.setMarkGroups(
|
|
36739
|
+
this.settingsDialog.setMarkGroups(
|
|
36740
|
+
this.markGroupsForEventsTab(),
|
|
36741
|
+
(id) => markGroupVisible2(this.scene.marks, id, this.scene.markGroups),
|
|
36742
|
+
(id) => markGroupOwnVisible(this.scene.marks.groups, id, this.scene.markGroups)
|
|
36743
|
+
);
|
|
36604
36744
|
this.settingsDialog.setHiddenSettings(this.hiddenSettings);
|
|
36605
36745
|
this.syncThemeControl();
|
|
36606
36746
|
this.settingsDialog.toggle(
|
|
@@ -36608,13 +36748,24 @@ var NativeRenderer = class {
|
|
|
36608
36748
|
(patch) => this.applyConfig(patch),
|
|
36609
36749
|
(json) => this.applyConfig(json),
|
|
36610
36750
|
() => {
|
|
36611
|
-
if (this.factoryConfig) this.applyConfig(
|
|
36612
|
-
this.settingsDialog?.
|
|
36613
|
-
this.openSettingsDialog();
|
|
36751
|
+
if (this.factoryConfig) this.applyConfig(this.factoryResetDocument(this.factoryConfig));
|
|
36752
|
+
this.settingsDialog?.refresh(this.getConfig());
|
|
36614
36753
|
},
|
|
36615
36754
|
section
|
|
36616
36755
|
);
|
|
36617
36756
|
}
|
|
36757
|
+
/**
|
|
36758
|
+
* The document "Reset defaults" applies: every setting back to its first-run value,
|
|
36759
|
+
* with two things that are NOT settings held or resolved here — the price style
|
|
36760
|
+
* stays the one the user is looking at, and the timeline-mark groups (an additive
|
|
36761
|
+
* merge, like the type bags) are named back to their host-declared visibility.
|
|
36762
|
+
*/
|
|
36763
|
+
factoryResetDocument(factory) {
|
|
36764
|
+
const doc = factoryResetConfig(factory, this.scene.priceStyle);
|
|
36765
|
+
const groups = { ...doc.marks.groups };
|
|
36766
|
+
for (const g of this.markGroupsInUse()) groups[g.id] = g.visible !== false;
|
|
36767
|
+
return { ...doc, marks: { ...doc.marks, groups } };
|
|
36768
|
+
}
|
|
36618
36769
|
/** Close the in-chart dialogs (indicator settings + chart-settings gear). No-op when none are open. */
|
|
36619
36770
|
closeDialogs() {
|
|
36620
36771
|
this.inputsUI?.closeOpenDialog();
|
|
@@ -37677,6 +37828,15 @@ var NativeRenderer = class {
|
|
|
37677
37828
|
markGroupsInUse() {
|
|
37678
37829
|
return effectiveMarkGroups(this.scene.timelineMarks, this.scene.markGroups);
|
|
37679
37830
|
}
|
|
37831
|
+
/**
|
|
37832
|
+
* The groups as the Events tab lists them: nested only under a DEFINED parent. The
|
|
37833
|
+
* painter's visibility chain resolves parents against the defined groups alone, so a
|
|
37834
|
+
* parent that marks merely name must not nest (and dim) a child the painter still shows.
|
|
37835
|
+
*/
|
|
37836
|
+
markGroupsForEventsTab() {
|
|
37837
|
+
const defined = new Set(this.scene.markGroups.map((g) => g.id));
|
|
37838
|
+
return this.markGroupsInUse().map((g) => g.parent !== void 0 && !defined.has(g.parent) ? { ...g, parent: void 0 } : g);
|
|
37839
|
+
}
|
|
37680
37840
|
onViewportChange(cb) {
|
|
37681
37841
|
this.viewportCbs.add(cb);
|
|
37682
37842
|
return () => this.viewportCbs.delete(cb);
|
|
@@ -43569,6 +43729,11 @@ var ChartCell = class {
|
|
|
43569
43729
|
if (typeof zone === "string" && normalizeTimezone(zone) !== normalizeTimezone(this.deps.timezone())) {
|
|
43570
43730
|
this.deps.setTimezone(normalizeTimezone(zone));
|
|
43571
43731
|
}
|
|
43732
|
+
const style = this.priceStyle;
|
|
43733
|
+
if (style !== (this.state.priceStyle ?? "candles")) {
|
|
43734
|
+
this.state.priceStyle = style;
|
|
43735
|
+
this.deps.onPriceStyleChanged(this.id);
|
|
43736
|
+
}
|
|
43572
43737
|
this.syncStatuslineColors();
|
|
43573
43738
|
this.syncPlotOverlayTokens();
|
|
43574
43739
|
});
|
package/dist/widget.d.cts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-
|
|
2
|
-
export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-
|
|
3
|
-
import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-
|
|
4
|
-
import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-
|
|
5
|
-
export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-
|
|
1
|
+
import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-DYtiRtES.cjs';
|
|
2
|
+
export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-DYtiRtES.cjs';
|
|
3
|
+
import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-DNBoMKkX.cjs';
|
|
4
|
+
import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-gA__yaog.cjs';
|
|
5
|
+
export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-gA__yaog.cjs';
|
|
6
6
|
import { K as KeymapManager } from './keymap-CGOz5F5f.cjs';
|
|
7
|
-
import { a as SymbolDescriptor } from './DataProvider-
|
|
7
|
+
import { a as SymbolDescriptor } from './DataProvider-Dut6lXGM.cjs';
|
|
8
8
|
import { d as SidePanel } from './side-panel-HF0IAzwf.cjs';
|
|
9
9
|
export { D as DEFAULT_PANEL_MAX_WIDTH, a as DEFAULT_PANEL_MIN_WIDTH, b as DEFAULT_PANEL_WIDTH, S as SidePanelOptions, c as clampPanelWidth } from './side-panel-HF0IAzwf.cjs';
|
|
10
10
|
|
package/dist/widget.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-
|
|
2
|
-
export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-
|
|
3
|
-
import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-
|
|
4
|
-
import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-
|
|
5
|
-
export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-
|
|
1
|
+
import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-CEkgJKTU.js';
|
|
2
|
+
export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-CEkgJKTU.js';
|
|
3
|
+
import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-DNBoMKkX.js';
|
|
4
|
+
import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-DypGXjtr.js';
|
|
5
|
+
export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-DypGXjtr.js';
|
|
6
6
|
import { K as KeymapManager } from './keymap-CGOz5F5f.js';
|
|
7
|
-
import { a as SymbolDescriptor } from './DataProvider-
|
|
7
|
+
import { a as SymbolDescriptor } from './DataProvider-DLeFs1gE.js';
|
|
8
8
|
import { d as SidePanel } from './side-panel-HF0IAzwf.js';
|
|
9
9
|
export { D as DEFAULT_PANEL_MAX_WIDTH, a as DEFAULT_PANEL_MIN_WIDTH, b as DEFAULT_PANEL_WIDTH, S as SidePanelOptions, c as clampPanelWidth } from './side-panel-HF0IAzwf.js';
|
|
10
10
|
|
package/dist/widget.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { VelaWorkspace } from './chunk-
|
|
2
|
-
export { Bottombar, ChartContextMenu, DataWindow, IndicatorPicker, ObjectTree, PanelDock, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeQuick, Topbar, Watermark, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, localStorageAdapter, parseTimeframe, priceStyleLabel, resolveIndicators, sanitizeState, timeframeLabel, timeframeMs } from './chunk-
|
|
3
|
-
export { TIMEZONES, normalizeTimezone, tzButtonLabel, tzMenuLabel, tzOffset } from './chunk-
|
|
1
|
+
import { VelaWorkspace } from './chunk-MNG5XPLV.js';
|
|
2
|
+
export { Bottombar, ChartContextMenu, DataWindow, IndicatorPicker, ObjectTree, PanelDock, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeQuick, Topbar, Watermark, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, localStorageAdapter, parseTimeframe, priceStyleLabel, resolveIndicators, sanitizeState, timeframeLabel, timeframeMs } from './chunk-MNG5XPLV.js';
|
|
3
|
+
export { TIMEZONES, normalizeTimezone, tzButtonLabel, tzMenuLabel, tzOffset } from './chunk-MCLI6B3S.js';
|
|
4
4
|
export { DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, OVERRIDABLE_TOPBAR_IDS, SidePanel, TOPBAR_BUILTIN_IDS, TOPBAR_DEFAULT_LEFT, TOPBAR_DEFAULT_RIGHT, clampPanelWidth, pinnedTopbarActionIds, registerSidePanel, registerStatePersistence, registerSymbolRanking, registerWidgetAction, registerWidgetAttachment, resolveTopbarComposition, sidePanels, statePersistenceHandlers, symbolRanking, topbarActionOverride, topbarHas, unregisterSidePanel, unregisterStatePersistence, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments } from './chunk-BFA32GOU.js';
|
|
5
5
|
import './chunk-ZADTVRUO.js';
|
|
6
6
|
import './chunk-BKHSQ4YM.js';
|