@luxalgo/vela 0.7.6 → 0.7.7
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/{chunk-ZADTVRUO.js → chunk-PVGWNF7V.js} +1 -1
- package/dist/{chunk-JSVCWYBF.js → chunk-RVQWJOEE.js} +232 -112
- package/dist/{chunk-BKHSQ4YM.js → chunk-WTWGEB7K.js} +23 -9
- package/dist/{chunk-EMB53WNQ.js → chunk-ZA2XWTGH.js} +84 -31
- package/dist/{contributions-D6p1RB38.d.cts → contributions-DF_Ea07m.d.cts} +17 -0
- package/dist/{contributions-C7Wsm_S9.d.ts → contributions-nKOSeLy8.d.ts} +17 -0
- package/dist/index.cjs +240 -119
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +2 -2
- package/dist/{plugin-SodaQhjQ.d.ts → plugin-0oFDnexb.d.ts} +1 -1
- package/dist/{plugin-CxWfg6vK.d.cts → plugin-DPyVJFoA.d.cts} +1 -1
- package/dist/plugin.d.cts +2 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/{statusline-model-gWHrsOy3.d.cts → statusline-model-BoWJ3cWQ.d.cts} +16 -3
- package/dist/{statusline-model-xBiVsKoE.d.ts → statusline-model-DAFyqVmR.d.ts} +16 -3
- package/dist/ui.cjs +23 -9
- package/dist/ui.d.cts +19 -2
- package/dist/ui.d.ts +19 -2
- package/dist/ui.js +2 -2
- package/dist/vela.global.js +240 -119
- package/dist/vela.global.min.js +61 -51
- package/dist/widget.cjs +334 -147
- package/dist/widget.d.cts +5 -5
- package/dist/widget.d.ts +5 -5
- package/dist/widget.js +5 -5
- package/dist/workspace.cjs +334 -147
- package/dist/workspace.d.cts +33 -6
- package/dist/workspace.d.ts +33 -6
- package/dist/workspace.js +4 -4
- package/package.json +21 -1
package/dist/vela.global.js
CHANGED
|
@@ -20561,7 +20561,8 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20561
20561
|
recents.unshift(hex6);
|
|
20562
20562
|
if (recents.length > 10) recents.length = 10;
|
|
20563
20563
|
}
|
|
20564
|
-
function buildColorPicker(color, theme, onChange) {
|
|
20564
|
+
function buildColorPicker(color, theme, onChange, options = {}) {
|
|
20565
|
+
const commit = options.commit ?? "live";
|
|
20565
20566
|
const parsed = splitColor(color);
|
|
20566
20567
|
let curHex = parsed.hex6;
|
|
20567
20568
|
let curAlpha = parsed.alpha;
|
|
@@ -20644,7 +20645,12 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20644
20645
|
const r = track.getBoundingClientRect();
|
|
20645
20646
|
curAlpha = Math.max(0, Math.min(1, (clientX - r.left) / r.width));
|
|
20646
20647
|
paintOpacity();
|
|
20647
|
-
emit();
|
|
20648
|
+
if (commit === "live") emit();
|
|
20649
|
+
};
|
|
20650
|
+
const endDrag = () => {
|
|
20651
|
+
if (!dragging) return;
|
|
20652
|
+
dragging = false;
|
|
20653
|
+
if (commit === "release") emit();
|
|
20648
20654
|
};
|
|
20649
20655
|
track.addEventListener("pointerdown", (e) => {
|
|
20650
20656
|
e.stopPropagation();
|
|
@@ -20655,7 +20661,8 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20655
20661
|
track.addEventListener("pointermove", (e) => {
|
|
20656
20662
|
if (dragging) onDrag(e.clientX);
|
|
20657
20663
|
});
|
|
20658
|
-
track.addEventListener("pointerup",
|
|
20664
|
+
track.addEventListener("pointerup", endDrag);
|
|
20665
|
+
track.addEventListener("pointercancel", endDrag);
|
|
20659
20666
|
function emit() {
|
|
20660
20667
|
onChange(combineColor(curHex, curAlpha));
|
|
20661
20668
|
}
|
|
@@ -20678,7 +20685,7 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20678
20685
|
return root;
|
|
20679
20686
|
}
|
|
20680
20687
|
function colorField(theme, getVal, onVal, opts) {
|
|
20681
|
-
return new ColorField({ theme, getVal, onVal, shape: opts?.shape, id: opts?.id, popover: opts?.popover }).el;
|
|
20688
|
+
return new ColorField({ theme, getVal, onVal, shape: opts?.shape, id: opts?.id, popover: opts?.popover, commit: opts?.commit }).el;
|
|
20682
20689
|
}
|
|
20683
20690
|
var ColorField = class {
|
|
20684
20691
|
constructor(opts) {
|
|
@@ -20687,6 +20694,7 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20687
20694
|
this.getVal = opts.getVal;
|
|
20688
20695
|
this.onVal = opts.onVal;
|
|
20689
20696
|
this.popoverOpts = opts.popover;
|
|
20697
|
+
this.commit = opts.commit;
|
|
20690
20698
|
const trigger = document.createElement("button");
|
|
20691
20699
|
trigger.type = "button";
|
|
20692
20700
|
if (opts.id) trigger.id = opts.id;
|
|
@@ -20726,10 +20734,15 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
20726
20734
|
boundary: this.popoverOpts?.boundary,
|
|
20727
20735
|
zIndex: this.popoverOpts?.zIndex,
|
|
20728
20736
|
className: "vela-color-field-pop",
|
|
20729
|
-
content: buildColorPicker(
|
|
20730
|
-
this.
|
|
20731
|
-
this.
|
|
20732
|
-
|
|
20737
|
+
content: buildColorPicker(
|
|
20738
|
+
this.getVal(),
|
|
20739
|
+
this.theme,
|
|
20740
|
+
(val) => {
|
|
20741
|
+
this.onVal(val);
|
|
20742
|
+
this.paint();
|
|
20743
|
+
},
|
|
20744
|
+
{ commit: this.commit }
|
|
20745
|
+
)
|
|
20733
20746
|
});
|
|
20734
20747
|
pop.show();
|
|
20735
20748
|
}
|
|
@@ -21210,7 +21223,8 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
21210
21223
|
const el2 = colorField(desc.theme, desc.get, desc.onChange, {
|
|
21211
21224
|
shape: "circle",
|
|
21212
21225
|
id: desc.id,
|
|
21213
|
-
popover: desc.popover
|
|
21226
|
+
popover: desc.popover,
|
|
21227
|
+
commit: desc.commit
|
|
21214
21228
|
});
|
|
21215
21229
|
if (desc.title) el2.title = desc.title;
|
|
21216
21230
|
return { el: el2 };
|
|
@@ -21588,7 +21602,10 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
21588
21602
|
id,
|
|
21589
21603
|
theme: this.host.theme(),
|
|
21590
21604
|
get: () => String(bagOf(row, inp)[inp.key] ?? inp.defval),
|
|
21591
|
-
onChange: (v) => emit(v)
|
|
21605
|
+
onChange: (v) => emit(v),
|
|
21606
|
+
// An input change re-executes the script over its whole history: commit the
|
|
21607
|
+
// opacity drag once on release, not once per pointer move.
|
|
21608
|
+
commit: "release"
|
|
21592
21609
|
}).el;
|
|
21593
21610
|
}
|
|
21594
21611
|
if (inp.type === "symbol") return this.buildSymbol(id, String(current), emit);
|
|
@@ -21835,10 +21852,6 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
21835
21852
|
}
|
|
21836
21853
|
/** Open a themed month calendar under `anchor` — same surface + shadow as the choice list. */
|
|
21837
21854
|
openCalendar(anchor, current, onPick) {
|
|
21838
|
-
const parsed = parseIsoDate(current);
|
|
21839
|
-
let year = parsed?.getFullYear() ?? (/* @__PURE__ */ new Date()).getFullYear();
|
|
21840
|
-
let month = parsed?.getMonth() ?? (/* @__PURE__ */ new Date()).getMonth();
|
|
21841
|
-
const selected = parsed ? isoDate(parsed) : current;
|
|
21842
21855
|
const pop = new Popover({
|
|
21843
21856
|
trigger: anchor,
|
|
21844
21857
|
theme: this.host.theme(),
|
|
@@ -21850,80 +21863,10 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
21850
21863
|
this.calendarPop = null;
|
|
21851
21864
|
this.calendarAnchor = null;
|
|
21852
21865
|
},
|
|
21853
|
-
content: (el) => {
|
|
21854
|
-
|
|
21855
|
-
|
|
21856
|
-
|
|
21857
|
-
prev3.type = "button";
|
|
21858
|
-
prev3.className = "vela-ind-cal-nav";
|
|
21859
|
-
prev3.setAttribute("aria-label", "Previous month");
|
|
21860
|
-
prev3.innerHTML = iconAt("chevron-left", 14);
|
|
21861
|
-
const next2 = document.createElement("button");
|
|
21862
|
-
next2.type = "button";
|
|
21863
|
-
next2.className = "vela-ind-cal-nav";
|
|
21864
|
-
next2.setAttribute("aria-label", "Next month");
|
|
21865
|
-
next2.innerHTML = iconAt("chevron-right", 14);
|
|
21866
|
-
const head = document.createElement("div");
|
|
21867
|
-
head.className = "vela-ind-cal-head";
|
|
21868
|
-
head.append(prev3, title, next2);
|
|
21869
|
-
const week = document.createElement("div");
|
|
21870
|
-
week.className = "vela-ind-cal-week";
|
|
21871
|
-
for (const d of WEEKDAY_LABELS) {
|
|
21872
|
-
const cell = document.createElement("span");
|
|
21873
|
-
cell.textContent = d;
|
|
21874
|
-
week.appendChild(cell);
|
|
21875
|
-
}
|
|
21876
|
-
const grid = document.createElement("div");
|
|
21877
|
-
grid.className = "vela-ind-cal-grid";
|
|
21878
|
-
const paint = () => {
|
|
21879
|
-
title.textContent = `${MONTH_LABELS[month]} ${year}`;
|
|
21880
|
-
grid.replaceChildren();
|
|
21881
|
-
const first2 = new Date(year, month, 1);
|
|
21882
|
-
const startPad = first2.getDay();
|
|
21883
|
-
const days = new Date(year, month + 1, 0).getDate();
|
|
21884
|
-
const today = isoDate(/* @__PURE__ */ new Date());
|
|
21885
|
-
for (let i = 0; i < startPad; i++) {
|
|
21886
|
-
const blank = document.createElement("span");
|
|
21887
|
-
blank.className = "vela-ind-cal-blank";
|
|
21888
|
-
grid.appendChild(blank);
|
|
21889
|
-
}
|
|
21890
|
-
for (let day = 1; day <= days; day++) {
|
|
21891
|
-
const iso = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
21892
|
-
const b = document.createElement("button");
|
|
21893
|
-
b.type = "button";
|
|
21894
|
-
b.className = "vela-ind-cal-day";
|
|
21895
|
-
b.textContent = String(day);
|
|
21896
|
-
if (iso === selected) b.dataset.checked = "1";
|
|
21897
|
-
if (iso === today) b.dataset.today = "1";
|
|
21898
|
-
b.addEventListener("click", (e) => {
|
|
21899
|
-
e.stopPropagation();
|
|
21900
|
-
pop.hide();
|
|
21901
|
-
onPick(iso);
|
|
21902
|
-
});
|
|
21903
|
-
grid.appendChild(b);
|
|
21904
|
-
}
|
|
21905
|
-
};
|
|
21906
|
-
prev3.addEventListener("click", (e) => {
|
|
21907
|
-
e.stopPropagation();
|
|
21908
|
-
month -= 1;
|
|
21909
|
-
if (month < 0) {
|
|
21910
|
-
month = 11;
|
|
21911
|
-
year -= 1;
|
|
21912
|
-
}
|
|
21913
|
-
paint();
|
|
21914
|
-
});
|
|
21915
|
-
next2.addEventListener("click", (e) => {
|
|
21916
|
-
e.stopPropagation();
|
|
21917
|
-
month += 1;
|
|
21918
|
-
if (month > 11) {
|
|
21919
|
-
month = 0;
|
|
21920
|
-
year += 1;
|
|
21921
|
-
}
|
|
21922
|
-
paint();
|
|
21923
|
-
});
|
|
21924
|
-
paint();
|
|
21925
|
-
el.append(head, week, grid);
|
|
21926
|
-
}
|
|
21866
|
+
content: (el) => fillCalendar(el, current, (iso) => {
|
|
21867
|
+
pop.hide();
|
|
21868
|
+
onPick(iso);
|
|
21869
|
+
})
|
|
21927
21870
|
});
|
|
21928
21871
|
this.calendarPop = pop;
|
|
21929
21872
|
this.calendarAnchor = anchor;
|
|
@@ -22032,7 +21975,7 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
22032
21975
|
var CALENDAR_SVG = iconAt("calendar", 14);
|
|
22033
21976
|
var CLOCK_SVG = iconAt("clock", 14);
|
|
22034
21977
|
var DIALOG_STYLE_ID2 = "vela-ind-dialog-styles";
|
|
22035
|
-
var DIALOG_STYLE_REV = "
|
|
21978
|
+
var DIALOG_STYLE_REV = "30";
|
|
22036
21979
|
var LEGEND_ICON_PX = 16;
|
|
22037
21980
|
function ensureDialogStyles() {
|
|
22038
21981
|
if (typeof document === "undefined") return;
|
|
@@ -22048,8 +21991,12 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
22048
21991
|
.vela-ind-combo-chevron{position:absolute;right:0;top:0;bottom:0;width:26px;border:none;background:transparent;color:inherit;opacity:0.55;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;}
|
|
22049
21992
|
.vela-ind-combo-chevron:hover{opacity:0.9;}
|
|
22050
21993
|
.vela-ind-cal{background:var(--vela-bg);color:var(--vela-fg);border:none;border-radius:6px;box-shadow:var(--vela-shadow);font:14px var(--vela-font);padding:10px 12px;user-select:none;}
|
|
21994
|
+
.vela-ind-cal [hidden]{display:none !important;}
|
|
22051
21995
|
.vela-ind-cal-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px;}
|
|
22052
|
-
.vela-ind-cal-title{flex:1;
|
|
21996
|
+
.vela-ind-cal-title{flex:1;display:flex;align-items:center;justify-content:center;gap:2px;min-width:0;}
|
|
21997
|
+
.vela-ind-cal-switch{border:none;background:transparent;color:var(--vela-fg-bright);font:inherit;font-weight:600;font-size:14px;padding:2px 6px;border-radius:4px;cursor:pointer;}
|
|
21998
|
+
.vela-ind-cal-switch:not(:disabled):hover{background:var(--vela-hover);}
|
|
21999
|
+
.vela-ind-cal-switch:disabled{cursor:default;}
|
|
22053
22000
|
.vela-ind-cal-nav{width:24px;height:24px;border:none;background:transparent;color:var(--vela-fg-muted);border-radius:4px;padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;}
|
|
22054
22001
|
.vela-ind-cal-nav:hover{background:var(--vela-hover);color:var(--vela-fg-bright);}
|
|
22055
22002
|
.vela-ind-cal-week,.vela-ind-cal-grid{display:grid;grid-template-columns:repeat(7,28px);gap:2px;}
|
|
@@ -22060,6 +22007,12 @@ ${overlayScrollbarCss(".vela-dialog *")}
|
|
|
22060
22007
|
.vela-ind-cal-day:hover{background:var(--vela-hover);}
|
|
22061
22008
|
.vela-ind-cal-day[data-checked]{background:var(--vela-hover-strong);color:var(--vela-fg-bright);}
|
|
22062
22009
|
.vela-ind-cal-day[data-today]:not([data-checked]){box-shadow:inset 0 0 0 1px var(--vela-border-strong);}
|
|
22010
|
+
.vela-ind-cal-cells{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;width:calc(7 * 28px + 6 * 2px);}
|
|
22011
|
+
.vela-ind-cal-cell{height:36px;border:none;background:transparent;color:inherit;border-radius:4px;padding:0 4px;cursor:pointer;font:inherit;font-size:14px;}
|
|
22012
|
+
.vela-ind-cal-cell:hover{background:var(--vela-hover);}
|
|
22013
|
+
.vela-ind-cal-cell[data-checked]{background:var(--vela-hover-strong);color:var(--vela-fg-bright);}
|
|
22014
|
+
.vela-ind-cal-cell[data-today]:not([data-checked]){box-shadow:inset 0 0 0 1px var(--vela-border-strong);}
|
|
22015
|
+
.vela-ind-cal-cell[data-outside]{opacity:0.45;}
|
|
22063
22016
|
${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
22064
22017
|
.vela-ind-tab{font-weight:600;font-size:13px;line-height:20px;transition:color var(--vela-dur-fast) ease,border-color var(--vela-dur-fast) ease;}
|
|
22065
22018
|
.vela-ind-tab:not(.vela-ind-tab-active):hover{color:var(--vela-fg-bright);}
|
|
@@ -22094,6 +22047,7 @@ ${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
|
22094
22047
|
return { value: v, label: v };
|
|
22095
22048
|
});
|
|
22096
22049
|
var MONTH_LABELS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
22050
|
+
var MONTH_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
22097
22051
|
var WEEKDAY_LABELS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
22098
22052
|
function normalizeDateInput(raw) {
|
|
22099
22053
|
const t = raw.trim();
|
|
@@ -22115,6 +22069,151 @@ ${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
|
22115
22069
|
function isoDate(d) {
|
|
22116
22070
|
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
22117
22071
|
}
|
|
22072
|
+
function fillCalendar(el, current, onPick) {
|
|
22073
|
+
const today = /* @__PURE__ */ new Date();
|
|
22074
|
+
const selected = parseIsoDate(current);
|
|
22075
|
+
let year = selected?.getFullYear() ?? today.getFullYear();
|
|
22076
|
+
let month = selected?.getMonth() ?? today.getMonth();
|
|
22077
|
+
let mode = "date";
|
|
22078
|
+
const prev3 = document.createElement("button");
|
|
22079
|
+
prev3.type = "button";
|
|
22080
|
+
prev3.className = "vela-ind-cal-nav";
|
|
22081
|
+
prev3.innerHTML = iconAt("chevron-left", 14);
|
|
22082
|
+
const next2 = document.createElement("button");
|
|
22083
|
+
next2.type = "button";
|
|
22084
|
+
next2.className = "vela-ind-cal-nav";
|
|
22085
|
+
next2.innerHTML = iconAt("chevron-right", 14);
|
|
22086
|
+
const monthBtn = document.createElement("button");
|
|
22087
|
+
monthBtn.type = "button";
|
|
22088
|
+
monthBtn.className = "vela-ind-cal-switch";
|
|
22089
|
+
monthBtn.setAttribute("aria-label", "Choose month");
|
|
22090
|
+
const yearBtn = document.createElement("button");
|
|
22091
|
+
yearBtn.type = "button";
|
|
22092
|
+
yearBtn.className = "vela-ind-cal-switch";
|
|
22093
|
+
yearBtn.setAttribute("aria-label", "Choose year");
|
|
22094
|
+
const title = document.createElement("div");
|
|
22095
|
+
title.className = "vela-ind-cal-title";
|
|
22096
|
+
title.append(monthBtn, yearBtn);
|
|
22097
|
+
const head = document.createElement("div");
|
|
22098
|
+
head.className = "vela-ind-cal-head";
|
|
22099
|
+
head.append(prev3, title, next2);
|
|
22100
|
+
const week = document.createElement("div");
|
|
22101
|
+
week.className = "vela-ind-cal-week";
|
|
22102
|
+
for (const d of WEEKDAY_LABELS) {
|
|
22103
|
+
const cell = document.createElement("span");
|
|
22104
|
+
cell.textContent = d;
|
|
22105
|
+
week.appendChild(cell);
|
|
22106
|
+
}
|
|
22107
|
+
const grid = document.createElement("div");
|
|
22108
|
+
const paint = () => {
|
|
22109
|
+
const decade = Math.floor(year / 10) * 10;
|
|
22110
|
+
monthBtn.hidden = mode !== "date";
|
|
22111
|
+
monthBtn.textContent = MONTH_LABELS[month] ?? "";
|
|
22112
|
+
yearBtn.textContent = mode === "year" ? `${decade}-${decade + 9}` : String(year);
|
|
22113
|
+
yearBtn.disabled = mode === "year";
|
|
22114
|
+
week.hidden = mode !== "date";
|
|
22115
|
+
prev3.setAttribute("aria-label", mode === "date" ? "Previous month" : mode === "month" ? "Previous year" : "Previous decade");
|
|
22116
|
+
next2.setAttribute("aria-label", mode === "date" ? "Next month" : mode === "month" ? "Next year" : "Next decade");
|
|
22117
|
+
grid.className = mode === "date" ? "vela-ind-cal-grid" : "vela-ind-cal-cells";
|
|
22118
|
+
grid.replaceChildren();
|
|
22119
|
+
if (mode === "date") {
|
|
22120
|
+
const startPad = new Date(year, month, 1).getDay();
|
|
22121
|
+
const days = new Date(year, month + 1, 0).getDate();
|
|
22122
|
+
const todayIso = isoDate(today);
|
|
22123
|
+
const selectedIso = selected ? isoDate(selected) : "";
|
|
22124
|
+
for (let i = 0; i < startPad; i++) {
|
|
22125
|
+
const blank = document.createElement("span");
|
|
22126
|
+
blank.className = "vela-ind-cal-blank";
|
|
22127
|
+
grid.appendChild(blank);
|
|
22128
|
+
}
|
|
22129
|
+
for (let day = 1; day <= days; day++) {
|
|
22130
|
+
const iso = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
22131
|
+
const b = document.createElement("button");
|
|
22132
|
+
b.type = "button";
|
|
22133
|
+
b.className = "vela-ind-cal-day";
|
|
22134
|
+
b.textContent = String(day);
|
|
22135
|
+
if (iso === selectedIso) b.dataset.checked = "1";
|
|
22136
|
+
if (iso === todayIso) b.dataset.today = "1";
|
|
22137
|
+
b.addEventListener("click", (e) => {
|
|
22138
|
+
e.stopPropagation();
|
|
22139
|
+
onPick(iso);
|
|
22140
|
+
});
|
|
22141
|
+
grid.appendChild(b);
|
|
22142
|
+
}
|
|
22143
|
+
return;
|
|
22144
|
+
}
|
|
22145
|
+
if (mode === "month") {
|
|
22146
|
+
for (let m = 0; m < 12; m++) {
|
|
22147
|
+
const b = document.createElement("button");
|
|
22148
|
+
b.type = "button";
|
|
22149
|
+
b.className = "vela-ind-cal-cell";
|
|
22150
|
+
b.textContent = MONTH_SHORT[m] ?? "";
|
|
22151
|
+
if (selected?.getFullYear() === year && selected.getMonth() === m) b.dataset.checked = "1";
|
|
22152
|
+
if (today.getFullYear() === year && today.getMonth() === m) b.dataset.today = "1";
|
|
22153
|
+
b.addEventListener("click", (e) => {
|
|
22154
|
+
e.stopPropagation();
|
|
22155
|
+
month = m;
|
|
22156
|
+
mode = "date";
|
|
22157
|
+
paint();
|
|
22158
|
+
});
|
|
22159
|
+
grid.appendChild(b);
|
|
22160
|
+
}
|
|
22161
|
+
return;
|
|
22162
|
+
}
|
|
22163
|
+
for (let y = decade - 1; y <= decade + 10; y++) {
|
|
22164
|
+
const b = document.createElement("button");
|
|
22165
|
+
b.type = "button";
|
|
22166
|
+
b.className = "vela-ind-cal-cell";
|
|
22167
|
+
b.textContent = String(y);
|
|
22168
|
+
if (y < decade || y > decade + 9) b.dataset.outside = "1";
|
|
22169
|
+
if (selected?.getFullYear() === y) b.dataset.checked = "1";
|
|
22170
|
+
if (today.getFullYear() === y) b.dataset.today = "1";
|
|
22171
|
+
b.addEventListener("click", (e) => {
|
|
22172
|
+
e.stopPropagation();
|
|
22173
|
+
year = y;
|
|
22174
|
+
mode = "month";
|
|
22175
|
+
paint();
|
|
22176
|
+
});
|
|
22177
|
+
grid.appendChild(b);
|
|
22178
|
+
}
|
|
22179
|
+
};
|
|
22180
|
+
const step = (dir) => {
|
|
22181
|
+
if (mode === "date") {
|
|
22182
|
+
month += dir;
|
|
22183
|
+
if (month < 0) {
|
|
22184
|
+
month = 11;
|
|
22185
|
+
year -= 1;
|
|
22186
|
+
}
|
|
22187
|
+
if (month > 11) {
|
|
22188
|
+
month = 0;
|
|
22189
|
+
year += 1;
|
|
22190
|
+
}
|
|
22191
|
+
} else {
|
|
22192
|
+
year += mode === "month" ? dir : dir * 10;
|
|
22193
|
+
}
|
|
22194
|
+
paint();
|
|
22195
|
+
};
|
|
22196
|
+
prev3.addEventListener("click", (e) => {
|
|
22197
|
+
e.stopPropagation();
|
|
22198
|
+
step(-1);
|
|
22199
|
+
});
|
|
22200
|
+
next2.addEventListener("click", (e) => {
|
|
22201
|
+
e.stopPropagation();
|
|
22202
|
+
step(1);
|
|
22203
|
+
});
|
|
22204
|
+
monthBtn.addEventListener("click", (e) => {
|
|
22205
|
+
e.stopPropagation();
|
|
22206
|
+
mode = "month";
|
|
22207
|
+
paint();
|
|
22208
|
+
});
|
|
22209
|
+
yearBtn.addEventListener("click", (e) => {
|
|
22210
|
+
e.stopPropagation();
|
|
22211
|
+
mode = "year";
|
|
22212
|
+
paint();
|
|
22213
|
+
});
|
|
22214
|
+
paint();
|
|
22215
|
+
el.append(head, week, grid);
|
|
22216
|
+
}
|
|
22118
22217
|
function normalizeTimeInput(raw) {
|
|
22119
22218
|
const t = raw.trim();
|
|
22120
22219
|
const m = /^(\d{1,2}):(\d{2})$/.exec(t) ?? /^(\d{2})(\d{2})$/.exec(t);
|
|
@@ -23396,10 +23495,12 @@ ${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
|
23396
23495
|
var PREMARKET_SHADE = withAlpha(WARNING, 0.08);
|
|
23397
23496
|
var POSTMARKET_SHADE = withAlpha(ACCENT, 0.08);
|
|
23398
23497
|
var EXTENDED_SHADE = POSTMARKET_SHADE;
|
|
23498
|
+
var DEFAULT_MARGINS = { top: 10, bottom: 10, right: 10 };
|
|
23399
23499
|
function defaultChartStyle() {
|
|
23400
23500
|
return {
|
|
23401
23501
|
chartTypes: {},
|
|
23402
23502
|
fontSize: 11,
|
|
23503
|
+
margins: { ...DEFAULT_MARGINS },
|
|
23403
23504
|
gridVert: { visible: true, color: null },
|
|
23404
23505
|
gridHorz: { visible: true, color: null },
|
|
23405
23506
|
borderColor: null,
|
|
@@ -23523,6 +23624,12 @@ ${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
|
23523
23624
|
function clampSpacing(v) {
|
|
23524
23625
|
return v < 0.1 ? 0.1 : v > 10 ? 10 : v;
|
|
23525
23626
|
}
|
|
23627
|
+
function clampMarginPct(v) {
|
|
23628
|
+
return v < 0 ? 0 : v > 40 ? 40 : v;
|
|
23629
|
+
}
|
|
23630
|
+
function clampMarginBars(v) {
|
|
23631
|
+
return Math.round(v < 0 ? 0 : v > 200 ? 200 : v);
|
|
23632
|
+
}
|
|
23526
23633
|
function factoryResetConfig(factory, priceStyle = factory.series.style) {
|
|
23527
23634
|
const bag = {};
|
|
23528
23635
|
for (const t of chartTypes()) {
|
|
@@ -23571,6 +23678,7 @@ ${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
|
23571
23678
|
const ps = asObject(p.priceScale);
|
|
23572
23679
|
const anim = asObject(p.animations);
|
|
23573
23680
|
const panes = asObject(p.panes);
|
|
23681
|
+
const margins = asObject(p.margins);
|
|
23574
23682
|
const trades = asObject(p.trades);
|
|
23575
23683
|
const ts = asObject(p.timeScale);
|
|
23576
23684
|
const marks = asObject(p.marks);
|
|
@@ -23630,6 +23738,11 @@ ${overlayScrollbarCss(".vela-dialog.vela-ind-dialog *", 9)}
|
|
|
23630
23738
|
panes: {
|
|
23631
23739
|
separatorColor: isColor(panes.separatorColor) ? panes.separatorColor : base.panes.separatorColor
|
|
23632
23740
|
},
|
|
23741
|
+
margins: {
|
|
23742
|
+
top: isNum(margins.top) ? clampMarginPct(margins.top) : base.margins.top,
|
|
23743
|
+
bottom: isNum(margins.bottom) ? clampMarginPct(margins.bottom) : base.margins.bottom,
|
|
23744
|
+
right: isNum(margins.right) ? clampMarginBars(margins.right) : base.margins.right
|
|
23745
|
+
},
|
|
23633
23746
|
trades: {
|
|
23634
23747
|
visible: isBool(trades.visible) ? trades.visible : base.trades.visible,
|
|
23635
23748
|
labels: isBool(trades.labels) ? trades.labels : base.trades.labels,
|
|
@@ -29000,6 +29113,10 @@ void main() {
|
|
|
29000
29113
|
"canvas.grid",
|
|
29001
29114
|
"canvas.grid.vertical",
|
|
29002
29115
|
"canvas.grid.horizontal",
|
|
29116
|
+
"canvas.margins",
|
|
29117
|
+
"canvas.margins.top",
|
|
29118
|
+
"canvas.margins.bottom",
|
|
29119
|
+
"canvas.margins.right",
|
|
29003
29120
|
"canvas.theme"
|
|
29004
29121
|
];
|
|
29005
29122
|
function settingsIdCatalog(hostSections, markGroups = []) {
|
|
@@ -29530,6 +29647,10 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
29530
29647
|
body.append(sid(this.toggleRow("Horizontal", config.grid.horzLines.visible, (v) => this.emit({ grid: { horzLines: { visible: v } } }), [
|
|
29531
29648
|
this.swatch(config.grid.horzLines.color, (v) => this.emit({ grid: { horzLines: { color: v } } }))
|
|
29532
29649
|
]), "canvas.grid.horizontal"));
|
|
29650
|
+
body.append(sid(this.sectionTitle("Margins"), "canvas.margins"));
|
|
29651
|
+
body.append(sid(this.numberRow("Top", config.margins.top, 0, 40, 1, (v) => this.emit({ margins: { top: v } }), "%"), "canvas.margins.top"));
|
|
29652
|
+
body.append(sid(this.numberRow("Bottom", config.margins.bottom, 0, 40, 1, (v) => this.emit({ margins: { bottom: v } }), "%"), "canvas.margins.bottom"));
|
|
29653
|
+
body.append(sid(this.numberRow("Right", config.margins.right, 0, 200, 1, (v) => this.emit({ margins: { right: v } }), "bars"), "canvas.margins.right"));
|
|
29533
29654
|
if (this.themeControl) {
|
|
29534
29655
|
const tc = this.themeControl;
|
|
29535
29656
|
body.append(sid(this.sectionTitle("Theme"), "canvas.theme"));
|
|
@@ -30101,23 +30222,16 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
30101
30222
|
this.hintTips.push(dispose);
|
|
30102
30223
|
return el;
|
|
30103
30224
|
}
|
|
30104
|
-
|
|
30105
|
-
|
|
30106
|
-
|
|
30107
|
-
|
|
30108
|
-
|
|
30109
|
-
|
|
30110
|
-
|
|
30111
|
-
|
|
30112
|
-
|
|
30113
|
-
|
|
30114
|
-
step,
|
|
30115
|
-
fill: false,
|
|
30116
|
-
commit: "live",
|
|
30117
|
-
steppers: true,
|
|
30118
|
-
onChange
|
|
30119
|
-
}).el
|
|
30120
|
-
});
|
|
30225
|
+
/** `unit` (optional) trails the input as muted text — "%", "bars". */
|
|
30226
|
+
numberRow(label, value, min2, max2, step, onChange, unit) {
|
|
30227
|
+
const controls = [buildFieldControl({ kind: "number", value, min: min2, max: max2, step, fill: false, commit: "live", steppers: true, onChange }).el];
|
|
30228
|
+
if (unit) {
|
|
30229
|
+
const u = document.createElement("span");
|
|
30230
|
+
u.textContent = unit;
|
|
30231
|
+
u.style.cssText = "color:var(--vela-fg-muted);";
|
|
30232
|
+
controls.push(u);
|
|
30233
|
+
}
|
|
30234
|
+
return this.rowWith(label, controls);
|
|
30121
30235
|
}
|
|
30122
30236
|
/** A dropdown whose option values differ from their display labels. */
|
|
30123
30237
|
selectRowLabeled(label, value, options, onChange) {
|
|
@@ -35636,9 +35750,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
35636
35750
|
}
|
|
35637
35751
|
|
|
35638
35752
|
// src/renderers/native/core/autoscale.ts
|
|
35639
|
-
|
|
35640
|
-
var MARGIN_BOTTOM = 1 / 7;
|
|
35641
|
-
function computePaneScale(models, bars, includeCandles, i0, i1, drawings, log = false, offsetOf = () => 0) {
|
|
35753
|
+
function computePaneScale(models, bars, includeCandles, i0, i1, drawings, log = false, offsetOf = () => 0, margins = DEFAULT_MARGINS) {
|
|
35642
35754
|
let min2 = Infinity;
|
|
35643
35755
|
let max2 = -Infinity;
|
|
35644
35756
|
const consider = (v) => {
|
|
@@ -35673,14 +35785,17 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
35673
35785
|
const pad = Math.abs(min2) * 0.1 || 1;
|
|
35674
35786
|
return { min: min2 - pad, max: max2 + pad, log: log && min2 - pad > 0 };
|
|
35675
35787
|
}
|
|
35788
|
+
const content = Math.max(0.1, 1 - (margins.top + margins.bottom) / 100);
|
|
35789
|
+
const above = margins.top / 100 / content;
|
|
35790
|
+
const below = margins.bottom / 100 / content;
|
|
35676
35791
|
if (log && min2 > 0) {
|
|
35677
35792
|
const lmin = Math.log(min2);
|
|
35678
35793
|
const lmax = Math.log(max2);
|
|
35679
35794
|
const lspan = lmax - lmin;
|
|
35680
|
-
return { min: Math.exp(lmin - lspan *
|
|
35795
|
+
return { min: Math.exp(lmin - lspan * below), max: Math.exp(lmax + lspan * above), log: true };
|
|
35681
35796
|
}
|
|
35682
35797
|
const span = max2 - min2;
|
|
35683
|
-
return { min: min2 - span *
|
|
35798
|
+
return { min: min2 - span * below, max: max2 + span * above };
|
|
35684
35799
|
}
|
|
35685
35800
|
function considerSeries(s, i0, i1, off, consider) {
|
|
35686
35801
|
if (!seriesInScale(s)) return;
|
|
@@ -37507,6 +37622,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
37507
37622
|
intro: this.intro.style !== false
|
|
37508
37623
|
},
|
|
37509
37624
|
panes: { separatorColor: s.separatorColor ?? t.borderColor },
|
|
37625
|
+
margins: { ...s.margins },
|
|
37510
37626
|
trades: {
|
|
37511
37627
|
visible: this.scene.tradeMarkers.visible,
|
|
37512
37628
|
labels: this.scene.tradeMarkers.labels,
|
|
@@ -37619,6 +37735,10 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
37619
37735
|
this.animAutoscale.toggle(next2.animations.autoscale);
|
|
37620
37736
|
this.intro = { style: next2.animations.intro ? this.introOnStyle : false, duration: this.intro.duration || INTRO_DURATION_DEFAULT_MS };
|
|
37621
37737
|
s.separatorColor = keepInherit(s.separatorColor, next2.panes.separatorColor, prevTheme.borderColor);
|
|
37738
|
+
if (next2.margins.right !== s.margins.right && this.coords.barCount > 0) {
|
|
37739
|
+
this.applyViewport({ barSpacing: this.coords.getViewport().barSpacing, rightOffset: next2.margins.right });
|
|
37740
|
+
}
|
|
37741
|
+
s.margins = { ...next2.margins };
|
|
37622
37742
|
this.scene.tradeMarkers = {
|
|
37623
37743
|
visible: next2.trades.visible,
|
|
37624
37744
|
labels: next2.trades.labels,
|
|
@@ -37862,7 +37982,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
37862
37982
|
/** Glide the view back to the most recent bars, keeping the current zoom (barSpacing). */
|
|
37863
37983
|
scrollToRealtime() {
|
|
37864
37984
|
if (this.coords.barCount === 0) return;
|
|
37865
|
-
this.glideRightOffset(
|
|
37985
|
+
this.glideRightOffset(this.scene.style.margins.right);
|
|
37866
37986
|
}
|
|
37867
37987
|
/** Ease rightOffset to `target` at constant zoom (see animTick's scroll glide);
|
|
37868
37988
|
* instant when the scroll glide is off. Shared by scroll-to-latest and panBy. */
|
|
@@ -39804,6 +39924,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
39804
39924
|
const pricePane = panes.find((p) => p.kind === "price") ?? null;
|
|
39805
39925
|
this.chrome.prepare(this.scene, this.coords, this.theme);
|
|
39806
39926
|
const animating = this.animator.active;
|
|
39927
|
+
const margins = this.scene.style.margins;
|
|
39807
39928
|
for (const pane of panes) {
|
|
39808
39929
|
if (pane.manualScale) {
|
|
39809
39930
|
pane.scaleTarget = pane.manualScale;
|
|
@@ -39819,7 +39940,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
39819
39940
|
if (or2) dr = dr ? { min: Math.min(dr.min, or2.min), max: Math.max(dr.max, or2.max) } : or2;
|
|
39820
39941
|
}
|
|
39821
39942
|
const includeCandles = pane.kind === "price" && (!this.scene.candlesHidden || this.priceLayersAnchoredToBars(masterModels) || !this.paneHasMeasurableContent(masterModels, dr));
|
|
39822
|
-
pane.scaleTarget = computePaneScale(masterModels, this.bars, includeCandles, i0, i1, dr, paneLogScale(this.scene, pane), (id) => this.scene.offsetOf(id));
|
|
39943
|
+
pane.scaleTarget = computePaneScale(masterModels, this.bars, includeCandles, i0, i1, dr, paneLogScale(this.scene, pane), (id) => this.scene.offsetOf(id), margins);
|
|
39823
39944
|
pane.percentBaseline = pane.kind === "price" ? this.bars[i0]?.close ?? 0 : this.firstVisibleValue(masterModels, i0);
|
|
39824
39945
|
pane.axisFormat = void 0;
|
|
39825
39946
|
pane.axisBands = void 0;
|
|
@@ -39830,7 +39951,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
39830
39951
|
pane.axisFormat = "volume";
|
|
39831
39952
|
}
|
|
39832
39953
|
} else if (this.layerNativesOwnPane(pane, masterModels)) {
|
|
39833
|
-
pane.scaleTarget = computePaneScale([], this.bars, true, i0, i1, dr, paneLogScale(this.scene, pane), (id) => this.scene.offsetOf(id));
|
|
39954
|
+
pane.scaleTarget = computePaneScale([], this.bars, true, i0, i1, dr, paneLogScale(this.scene, pane), (id) => this.scene.offsetOf(id), margins);
|
|
39834
39955
|
pane.percentBaseline = this.bars[i0]?.close ?? 0;
|
|
39835
39956
|
if (masterModels.every((m) => m.paneAxis != null)) {
|
|
39836
39957
|
pane.axisFormat = "none";
|
|
@@ -39859,7 +39980,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
39859
39980
|
continue;
|
|
39860
39981
|
}
|
|
39861
39982
|
const mdr = this.chrome.paneDrawingsRange([model], this.scene, false, vr);
|
|
39862
|
-
sl.scaleTarget = computePaneScale([model], this.bars, false, i0, i1, mdr, false, (id) => this.scene.offsetOf(id));
|
|
39983
|
+
sl.scaleTarget = computePaneScale([model], this.bars, false, i0, i1, mdr, false, (id) => this.scene.offsetOf(id), margins);
|
|
39863
39984
|
if (!animating || !sl.initialized) {
|
|
39864
39985
|
sl.scale = { ...sl.scaleTarget };
|
|
39865
39986
|
sl.initialized = true;
|
|
@@ -39900,13 +40021,13 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
39900
40021
|
for (const pane of this.scene.panes.values()) pane.manualScale = null;
|
|
39901
40022
|
for (const sl of this.scene.indicatorScales.values()) sl.manualScale = null;
|
|
39902
40023
|
const visibleBars = Math.min(n, 200);
|
|
39903
|
-
const rightOffset =
|
|
40024
|
+
const rightOffset = this.scene.style.margins.right;
|
|
39904
40025
|
const v = this.clampViewport(w / ((visibleBars + rightOffset) * this.coords.spacingScale), rightOffset);
|
|
39905
40026
|
this.coords.setViewport(v);
|
|
39906
40027
|
this.targetBarSpacing = v.barSpacing;
|
|
39907
40028
|
}
|
|
39908
40029
|
/** Re-frame after a series replacement (a symbol/timeframe switch): keep the user's
|
|
39909
|
-
* zoom (bar spacing), re-anchor the newest bars at the
|
|
40030
|
+
* zoom (bar spacing), re-anchor the newest bars at the configured right margin.
|
|
39910
40031
|
* `clampViewport`'s fit-all-bars floor deliberately does NOT apply — a progressive
|
|
39911
40032
|
* head may still be backfilling toward the previous depth, and raising the spacing
|
|
39912
40033
|
* to its temporary bar count would lose the zoom this exists to keep. */
|
|
@@ -39915,7 +40036,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
|
|
|
39915
40036
|
this.panVelocity = 0;
|
|
39916
40037
|
for (const pane of this.scene.panes.values()) pane.manualScale = null;
|
|
39917
40038
|
for (const sl of this.scene.indicatorScales.values()) sl.manualScale = null;
|
|
39918
|
-
const v = { barSpacing: clampBarSpacing(this.coords.getViewport().barSpacing), rightOffset:
|
|
40039
|
+
const v = { barSpacing: clampBarSpacing(this.coords.getViewport().barSpacing), rightOffset: this.scene.style.margins.right };
|
|
39919
40040
|
this.coords.setViewport(v);
|
|
39920
40041
|
this.targetBarSpacing = v.barSpacing;
|
|
39921
40042
|
}
|