acttrader-charts 1.2.0-beta.9 → 1.3.0-beta.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/dist/index.cjs +204 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +204 -3
- package/dist/index.js.map +1 -1
- package/dist/webview/chart.html +11 -11
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6574,6 +6574,21 @@ var MobileToolsSheet = class {
|
|
|
6574
6574
|
};
|
|
6575
6575
|
|
|
6576
6576
|
// src/ui/MobileHeader.ts
|
|
6577
|
+
var SERIES_OPTIONS = [
|
|
6578
|
+
{ value: "candlestick", label: "Candlestick" },
|
|
6579
|
+
{ value: "hollow", label: "Hollow Candles" },
|
|
6580
|
+
{ value: "ohlc", label: "OHLC Bars" },
|
|
6581
|
+
{ value: "line", label: "Line" },
|
|
6582
|
+
{ value: "area", label: "Area" },
|
|
6583
|
+
{ value: "heikinashi", label: "Heikin Ashi" },
|
|
6584
|
+
{ value: "volumecandles", label: "Volume Candles" },
|
|
6585
|
+
{ value: "linemarkers", label: "Line with Markers" },
|
|
6586
|
+
{ value: "step", label: "Step Line" },
|
|
6587
|
+
{ value: "hlcarea", label: "HLC Area" },
|
|
6588
|
+
{ value: "baseline", label: "Baseline" },
|
|
6589
|
+
{ value: "columns", label: "Columns" },
|
|
6590
|
+
{ value: "highlow", label: "High Low" }
|
|
6591
|
+
];
|
|
6577
6592
|
var TF_PILLS3 = ["1m", "5m", "15m", "1h", "4h", "1D", "1W"];
|
|
6578
6593
|
var TF_LABEL3 = {
|
|
6579
6594
|
"1m": "1m",
|
|
@@ -6618,14 +6633,21 @@ var IC_SETTINGS2 = (sz = 16) => lucide4(
|
|
|
6618
6633
|
1.75
|
|
6619
6634
|
);
|
|
6620
6635
|
var MobileHeader = class {
|
|
6621
|
-
constructor(onTimeframeChange, toolsController, onAskAiClick, onSettingsClick, currentTf, theme, fontFamily) {
|
|
6636
|
+
constructor(onTimeframeChange, toolsController, onAskAiClick, onSettingsClick, onSeriesChange, currentTf, currentSeries, theme, fontFamily) {
|
|
6622
6637
|
this.toolsBtn = null;
|
|
6623
6638
|
this.tfBtns = /* @__PURE__ */ new Map();
|
|
6624
6639
|
this.toolsActive = false;
|
|
6640
|
+
this.seriesBtn = null;
|
|
6641
|
+
this.seriesMenu = null;
|
|
6642
|
+
this.seriesMenuOpen = false;
|
|
6643
|
+
this.onDocPointerDown = null;
|
|
6644
|
+
this.onWinReposition = null;
|
|
6625
6645
|
this.onTimeframeChange = onTimeframeChange;
|
|
6626
6646
|
this.onAskAiClick = onAskAiClick;
|
|
6627
6647
|
this.onSettingsClick = onSettingsClick;
|
|
6648
|
+
this.onSeriesChange = onSeriesChange;
|
|
6628
6649
|
this.currentTf = currentTf;
|
|
6650
|
+
this.currentSeries = currentSeries;
|
|
6629
6651
|
this.theme = theme;
|
|
6630
6652
|
this.fontFamily = fontFamily ?? MONO_FONT2;
|
|
6631
6653
|
this.sheet = toolsController ? new MobileToolsSheet(theme, toolsController, this.fontFamily) : null;
|
|
@@ -6636,9 +6658,11 @@ var MobileHeader = class {
|
|
|
6636
6658
|
}
|
|
6637
6659
|
// ── Build ──────────────────────────────────────────────────────────────────
|
|
6638
6660
|
build() {
|
|
6661
|
+
this.closeSeriesMenu();
|
|
6639
6662
|
this.el.innerHTML = "";
|
|
6640
6663
|
this.tfBtns.clear();
|
|
6641
6664
|
this.toolsBtn = null;
|
|
6665
|
+
this.seriesBtn = null;
|
|
6642
6666
|
Object.assign(this.el.style, {
|
|
6643
6667
|
display: "flex",
|
|
6644
6668
|
alignItems: "center",
|
|
@@ -6692,6 +6716,41 @@ var MobileHeader = class {
|
|
|
6692
6716
|
});
|
|
6693
6717
|
this.el.appendChild(divider);
|
|
6694
6718
|
}
|
|
6719
|
+
if (this.onSeriesChange) {
|
|
6720
|
+
const btn = document.createElement("button");
|
|
6721
|
+
btn.setAttribute("data-testid", "m-chart-type-btn");
|
|
6722
|
+
btn.title = "Chart type";
|
|
6723
|
+
btn.innerHTML = this.seriesIconHtml(this.currentSeries);
|
|
6724
|
+
Object.assign(btn.style, {
|
|
6725
|
+
display: "flex",
|
|
6726
|
+
alignItems: "center",
|
|
6727
|
+
justifyContent: "center",
|
|
6728
|
+
padding: "6px",
|
|
6729
|
+
borderRadius: "4px",
|
|
6730
|
+
border: "none",
|
|
6731
|
+
whiteSpace: "nowrap",
|
|
6732
|
+
flexShrink: "0",
|
|
6733
|
+
cursor: "pointer",
|
|
6734
|
+
outline: "none",
|
|
6735
|
+
background: "transparent",
|
|
6736
|
+
color: this.theme.axisText,
|
|
6737
|
+
transition: "color 0.15s, background 0.15s"
|
|
6738
|
+
});
|
|
6739
|
+
btn.addEventListener("click", (e) => {
|
|
6740
|
+
e.stopPropagation();
|
|
6741
|
+
this.toggleSeriesMenu();
|
|
6742
|
+
});
|
|
6743
|
+
this.seriesBtn = btn;
|
|
6744
|
+
this.el.appendChild(btn);
|
|
6745
|
+
const d2 = document.createElement("div");
|
|
6746
|
+
Object.assign(d2.style, {
|
|
6747
|
+
width: "1px",
|
|
6748
|
+
height: "20px",
|
|
6749
|
+
background: this.theme.axisBorder,
|
|
6750
|
+
flexShrink: "0"
|
|
6751
|
+
});
|
|
6752
|
+
this.el.appendChild(d2);
|
|
6753
|
+
}
|
|
6695
6754
|
for (const tf of TF_PILLS3) {
|
|
6696
6755
|
const btn = document.createElement("button");
|
|
6697
6756
|
btn.setAttribute("data-testid", `m-tf-${TF_LABEL3[tf] ?? tf}`);
|
|
@@ -6792,6 +6851,135 @@ var MobileHeader = class {
|
|
|
6792
6851
|
btn.style.color = active ? t.ui.accent : t.topBar.btnColor;
|
|
6793
6852
|
}
|
|
6794
6853
|
}
|
|
6854
|
+
// ── Chart-type (series) picker ───────────────────────────────────────────────
|
|
6855
|
+
/** Current-series icon, sized for the header button (mirrors AdvancedToolbar). */
|
|
6856
|
+
seriesIconHtml(series) {
|
|
6857
|
+
const raw = ICON_SERIES[series] ?? ICON_SERIES.candlestick;
|
|
6858
|
+
return raw.replace(/width="\d+" height="\d+"/, 'width="18" height="18"');
|
|
6859
|
+
}
|
|
6860
|
+
toggleSeriesMenu() {
|
|
6861
|
+
if (this.seriesMenuOpen) this.closeSeriesMenu();
|
|
6862
|
+
else this.openSeriesMenu();
|
|
6863
|
+
}
|
|
6864
|
+
openSeriesMenu() {
|
|
6865
|
+
if (this.seriesMenuOpen || !this.seriesBtn || typeof document === "undefined") return;
|
|
6866
|
+
this.seriesMenu = this.buildSeriesMenu();
|
|
6867
|
+
document.body.appendChild(this.seriesMenu);
|
|
6868
|
+
this.seriesMenuOpen = true;
|
|
6869
|
+
this.positionSeriesMenu();
|
|
6870
|
+
this.styleSeriesBtnActive(true);
|
|
6871
|
+
this.onDocPointerDown = (e) => {
|
|
6872
|
+
const t = e.target;
|
|
6873
|
+
if (this.seriesMenu?.contains(t) || this.seriesBtn?.contains(t)) return;
|
|
6874
|
+
this.closeSeriesMenu();
|
|
6875
|
+
};
|
|
6876
|
+
this.onWinReposition = () => this.closeSeriesMenu();
|
|
6877
|
+
setTimeout(() => {
|
|
6878
|
+
if (!this.seriesMenuOpen) return;
|
|
6879
|
+
document.addEventListener("pointerdown", this.onDocPointerDown, true);
|
|
6880
|
+
window.addEventListener("resize", this.onWinReposition, true);
|
|
6881
|
+
window.addEventListener("scroll", this.onWinReposition, true);
|
|
6882
|
+
this.el.addEventListener("scroll", this.onWinReposition, true);
|
|
6883
|
+
}, 0);
|
|
6884
|
+
}
|
|
6885
|
+
closeSeriesMenu() {
|
|
6886
|
+
if (this.onDocPointerDown) {
|
|
6887
|
+
document.removeEventListener("pointerdown", this.onDocPointerDown, true);
|
|
6888
|
+
this.onDocPointerDown = null;
|
|
6889
|
+
}
|
|
6890
|
+
if (this.onWinReposition) {
|
|
6891
|
+
window.removeEventListener("resize", this.onWinReposition, true);
|
|
6892
|
+
window.removeEventListener("scroll", this.onWinReposition, true);
|
|
6893
|
+
this.el.removeEventListener("scroll", this.onWinReposition, true);
|
|
6894
|
+
this.onWinReposition = null;
|
|
6895
|
+
}
|
|
6896
|
+
this.seriesMenu?.remove();
|
|
6897
|
+
this.seriesMenu = null;
|
|
6898
|
+
this.seriesMenuOpen = false;
|
|
6899
|
+
this.styleSeriesBtnActive(false);
|
|
6900
|
+
}
|
|
6901
|
+
buildSeriesMenu() {
|
|
6902
|
+
const t = this.theme;
|
|
6903
|
+
const menu = document.createElement("div");
|
|
6904
|
+
menu.setAttribute("data-testid", "m-chart-type-menu");
|
|
6905
|
+
Object.assign(menu.style, {
|
|
6906
|
+
position: "fixed",
|
|
6907
|
+
zIndex: "2147483000",
|
|
6908
|
+
minWidth: "184px",
|
|
6909
|
+
maxHeight: "60vh",
|
|
6910
|
+
overflowY: "auto",
|
|
6911
|
+
padding: "4px",
|
|
6912
|
+
borderRadius: "8px",
|
|
6913
|
+
border: `1px solid ${t.axisBorder}`,
|
|
6914
|
+
background: t.background,
|
|
6915
|
+
boxShadow: "0 8px 28px rgba(0,0,0,0.35)",
|
|
6916
|
+
fontFamily: this.fontFamily,
|
|
6917
|
+
WebkitOverflowScrolling: "touch"
|
|
6918
|
+
});
|
|
6919
|
+
for (const opt of SERIES_OPTIONS) {
|
|
6920
|
+
const active = opt.value === this.currentSeries;
|
|
6921
|
+
const row = document.createElement("button");
|
|
6922
|
+
row.type = "button";
|
|
6923
|
+
row.setAttribute("data-testid", `m-chart-type-${opt.value}`);
|
|
6924
|
+
Object.assign(row.style, {
|
|
6925
|
+
display: "flex",
|
|
6926
|
+
alignItems: "center",
|
|
6927
|
+
gap: "10px",
|
|
6928
|
+
width: "100%",
|
|
6929
|
+
padding: "9px 10px",
|
|
6930
|
+
borderRadius: "6px",
|
|
6931
|
+
border: "none",
|
|
6932
|
+
cursor: "pointer",
|
|
6933
|
+
outline: "none",
|
|
6934
|
+
textAlign: "left",
|
|
6935
|
+
fontSize: "13px",
|
|
6936
|
+
fontFamily: this.fontFamily,
|
|
6937
|
+
background: active ? t.ui.accentBg : "transparent",
|
|
6938
|
+
color: active ? t.ui.accent : t.axisText
|
|
6939
|
+
});
|
|
6940
|
+
const icon = (ICON_SERIES[opt.value] ?? "").replace(/width="\d+" height="\d+"/, 'width="16" height="16"');
|
|
6941
|
+
const check = active ? ICON_CHECKMARK.replace(/width="\d+" height="\d+"/, 'width="16" height="16"') : "";
|
|
6942
|
+
row.innerHTML = `<span style="display:flex;flex-shrink:0;">${icon}</span><span style="flex:1;">${opt.label}</span><span style="display:flex;flex-shrink:0;width:16px;">${check}</span>`;
|
|
6943
|
+
row.addEventListener("mouseenter", () => {
|
|
6944
|
+
if (opt.value !== this.currentSeries) row.style.background = t.ui.accentBg;
|
|
6945
|
+
});
|
|
6946
|
+
row.addEventListener("mouseleave", () => {
|
|
6947
|
+
if (opt.value !== this.currentSeries) row.style.background = "transparent";
|
|
6948
|
+
});
|
|
6949
|
+
row.addEventListener("click", (e) => {
|
|
6950
|
+
e.stopPropagation();
|
|
6951
|
+
this.selectSeries(opt.value);
|
|
6952
|
+
});
|
|
6953
|
+
menu.appendChild(row);
|
|
6954
|
+
}
|
|
6955
|
+
return menu;
|
|
6956
|
+
}
|
|
6957
|
+
positionSeriesMenu() {
|
|
6958
|
+
if (!this.seriesMenu || !this.seriesBtn) return;
|
|
6959
|
+
const r = this.seriesBtn.getBoundingClientRect();
|
|
6960
|
+
const m = this.seriesMenu;
|
|
6961
|
+
m.style.top = `${r.bottom + 6}px`;
|
|
6962
|
+
m.style.left = `${r.left}px`;
|
|
6963
|
+
const mr = m.getBoundingClientRect();
|
|
6964
|
+
if (mr.right > window.innerWidth - 8) {
|
|
6965
|
+
m.style.left = `${Math.max(8, window.innerWidth - 8 - mr.width)}px`;
|
|
6966
|
+
}
|
|
6967
|
+
if (mr.bottom > window.innerHeight - 8) {
|
|
6968
|
+
m.style.top = `${Math.max(8, r.top - 6 - mr.height)}px`;
|
|
6969
|
+
}
|
|
6970
|
+
}
|
|
6971
|
+
selectSeries(series) {
|
|
6972
|
+
this.closeSeriesMenu();
|
|
6973
|
+
if (series === this.currentSeries) return;
|
|
6974
|
+
this.currentSeries = series;
|
|
6975
|
+
if (this.seriesBtn) this.seriesBtn.innerHTML = this.seriesIconHtml(series);
|
|
6976
|
+
this.onSeriesChange?.(series);
|
|
6977
|
+
}
|
|
6978
|
+
styleSeriesBtnActive(active) {
|
|
6979
|
+
if (!this.seriesBtn) return;
|
|
6980
|
+
this.seriesBtn.style.color = active ? this.theme.ui.accent : this.theme.axisText;
|
|
6981
|
+
this.seriesBtn.style.background = active ? this.theme.ui.accentBg : "transparent";
|
|
6982
|
+
}
|
|
6795
6983
|
// ── Public surface (drop-in parity with CompactToolbar) ──────────────────────
|
|
6796
6984
|
setTimeframe(tf) {
|
|
6797
6985
|
this.currentTf = tf;
|
|
@@ -6809,10 +6997,12 @@ var MobileHeader = class {
|
|
|
6809
6997
|
this.sheet?.setTheme(theme);
|
|
6810
6998
|
}
|
|
6811
6999
|
destroy() {
|
|
7000
|
+
this.closeSeriesMenu();
|
|
6812
7001
|
this.sheet?.destroy();
|
|
6813
7002
|
this.el.remove();
|
|
6814
7003
|
this.tfBtns.clear();
|
|
6815
7004
|
this.toolsBtn = null;
|
|
7005
|
+
this.seriesBtn = null;
|
|
6816
7006
|
}
|
|
6817
7007
|
// ── Forwarded to the "Draw & Indicators" sheet so its toggles stay in sync ───
|
|
6818
7008
|
/**
|
|
@@ -6828,15 +7018,24 @@ var MobileHeader = class {
|
|
|
6828
7018
|
this.sheet?.syncVolume(show);
|
|
6829
7019
|
}
|
|
6830
7020
|
// ── No-op stubs — controls this variant intentionally does not render ────────
|
|
6831
|
-
|
|
7021
|
+
/** Engine → header sync: reflect an external series change (restored layout
|
|
7022
|
+
* state, keyboard shortcut, etc.) on the chart-type button. */
|
|
7023
|
+
setSeries(series) {
|
|
7024
|
+
this.currentSeries = series;
|
|
7025
|
+
if (this.seriesBtn) this.seriesBtn.innerHTML = this.seriesIconHtml(series);
|
|
7026
|
+
if (this.seriesMenuOpen) {
|
|
7027
|
+
this.closeSeriesMenu();
|
|
7028
|
+
this.openSeriesMenu();
|
|
7029
|
+
}
|
|
6832
7030
|
}
|
|
6833
7031
|
setIndicatorOptions(_options) {
|
|
6834
7032
|
}
|
|
6835
7033
|
closeDropdown() {
|
|
6836
7034
|
this.sheet?.close();
|
|
7035
|
+
this.closeSeriesMenu();
|
|
6837
7036
|
}
|
|
6838
7037
|
get hasOpenDropdown() {
|
|
6839
|
-
return this.sheet?.isOpen ?? false;
|
|
7038
|
+
return (this.sheet?.isOpen ?? false) || this.seriesMenuOpen;
|
|
6840
7039
|
}
|
|
6841
7040
|
setFullscreen(_active) {
|
|
6842
7041
|
}
|
|
@@ -23726,7 +23925,9 @@ var _ChartEngine = class _ChartEngine {
|
|
|
23726
23925
|
toolsController,
|
|
23727
23926
|
config.onAskAiClick ?? null,
|
|
23728
23927
|
this.settingsEnabled ? () => this.openChartSettings() : null,
|
|
23928
|
+
(s) => this.setSeries(s),
|
|
23729
23929
|
this.timeframe,
|
|
23930
|
+
this.series,
|
|
23730
23931
|
this.theme,
|
|
23731
23932
|
this.uiConfig.topBar?.dropBtnFontFamily
|
|
23732
23933
|
);
|