@luxalgo/vela 0.6.16 → 0.6.18
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/README.md +4 -0
- package/dist/{DataProvider-XLdJB86x.d.ts → DataProvider-Cb-2lC5O.d.ts} +1 -1
- package/dist/{DataProvider-xH2VBcFT.d.cts → DataProvider-UtWw2CgJ.d.cts} +1 -1
- package/dist/{chunk-GIJYO4LO.js → chunk-22QJKGXX.js} +666 -189
- package/dist/{chunk-SEOO6YG7.js → chunk-BXF7VNNE.js} +181 -111
- package/dist/{chunk-6DPAYEGO.js → chunk-CAFCLMPF.js} +1 -0
- package/dist/{chunk-I77F2SVE.js → chunk-IFJJPXSV.js} +1 -1
- package/dist/{chunk-MGU3USTP.js → chunk-T5Z5YUCF.js} +1 -1
- package/dist/{chunk-Q3TFJNJW.js → chunk-XCBJU674.js} +2 -2
- package/dist/{contributions-BEkxwA5F.d.cts → contributions-5nz3PLRe.d.ts} +9 -4
- package/dist/{contributions-CoAX7_SF.d.ts → contributions-DEPRtkmG.d.cts} +9 -4
- package/dist/index.cjs +662 -185
- package/dist/index.d.cts +15 -6
- package/dist/index.d.ts +15 -6
- package/dist/index.js +4 -4
- package/dist/{options-bdSAtp7y.d.ts → options-BCRmYALw.d.cts} +24 -5
- package/dist/{options-bdSAtp7y.d.cts → options-BCRmYALw.d.ts} +24 -5
- package/dist/{plugin-CNUgbRNq.d.ts → plugin-CUtfLeqz.d.ts} +3 -3
- package/dist/{plugin-Dxyq35Zf.d.cts → plugin-DVUaROPo.d.cts} +3 -3
- package/dist/plugin.cjs +1 -0
- package/dist/plugin.d.cts +4 -4
- package/dist/plugin.d.ts +4 -4
- package/dist/plugin.js +2 -2
- package/dist/providers/binance.d.cts +2 -2
- package/dist/providers/binance.d.ts +2 -2
- package/dist/providers/coinbase.d.cts +2 -2
- package/dist/providers/coinbase.d.ts +2 -2
- package/dist/providers/hyperliquid.d.cts +2 -2
- package/dist/providers/hyperliquid.d.ts +2 -2
- package/dist/{statusline-model-CbPza-Wc.d.cts → statusline-model-7ECSDtgt.d.cts} +3 -3
- package/dist/{statusline-model-D7cWkw8A.d.ts → statusline-model-D1Fhs8Dk.d.ts} +3 -3
- package/dist/ui.cjs +1 -0
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +3 -3
- package/dist/vela.global.js +662 -185
- package/dist/vela.global.min.js +52 -53
- package/dist/widget.cjs +839 -291
- package/dist/widget.d.cts +39 -12
- package/dist/widget.d.ts +39 -12
- package/dist/widget.js +7 -7
- package/dist/workspace.cjs +839 -291
- package/dist/workspace.d.cts +5 -5
- package/dist/workspace.d.ts +5 -5
- package/dist/workspace.js +6 -6
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel, isGroupRow, defaultMemberOf, groupKeyOf, groupMembers, LEGEND_AT_TOP_ATTR, Vela, TypedEventBus, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore, timeframeToMs } from './chunk-
|
|
2
|
-
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, widgetAttachments, getDrawingType, inputDeltas } from './chunk-
|
|
3
|
-
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-
|
|
4
|
-
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-
|
|
5
|
-
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, iconAt, SESSION_OFF, SESSION_POST, SESSION_PRE, icon, categoricalColor } from './chunk-
|
|
1
|
+
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel, isGroupRow, defaultMemberOf, groupKeyOf, groupMembers, LEGEND_AT_TOP_ATTR, normalizeSession, Vela, TypedEventBus, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore, timeframeToMs } from './chunk-22QJKGXX.js';
|
|
2
|
+
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, widgetAttachments, getDrawingType, inputDeltas } from './chunk-IFJJPXSV.js';
|
|
3
|
+
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-XCBJU674.js';
|
|
4
|
+
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-T5Z5YUCF.js';
|
|
5
|
+
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, iconAt, SESSION_OFF, SESSION_POST, SESSION_PRE, icon, categoricalColor } from './chunk-CAFCLMPF.js';
|
|
6
6
|
import { baseOf } from './chunk-W4EJWLEO.js';
|
|
7
7
|
|
|
8
8
|
// src/widget/timeframe.ts
|
|
@@ -1263,6 +1263,9 @@ function paneLabel(pane, fallbackTitle) {
|
|
|
1263
1263
|
function indicatorLabel(i, fallbackTitle) {
|
|
1264
1264
|
return i.title || fallbackTitle(i.id) || i.id;
|
|
1265
1265
|
}
|
|
1266
|
+
function indicatorRowLabel(i, fallbackTitle) {
|
|
1267
|
+
return i.shorttitle || indicatorLabel(i, fallbackTitle);
|
|
1268
|
+
}
|
|
1266
1269
|
function paneRows(pane) {
|
|
1267
1270
|
return pane.items.flatMap((it) => it.kind === "row" ? [it.row] : []);
|
|
1268
1271
|
}
|
|
@@ -1394,7 +1397,7 @@ function paneItems(snap, pane, units) {
|
|
|
1394
1397
|
const indicatorRow = (i) => ({
|
|
1395
1398
|
kind: "indicator",
|
|
1396
1399
|
id: i.id,
|
|
1397
|
-
label:
|
|
1400
|
+
label: indicatorRowLabel(i, snap.handleTitle),
|
|
1398
1401
|
visible: snap.indicatorVisible(i.id),
|
|
1399
1402
|
ownScale: i.ownScale
|
|
1400
1403
|
});
|
|
@@ -1524,9 +1527,13 @@ var CSS4 = `
|
|
|
1524
1527
|
.vela-ot-empty { padding: 20px 10px; text-align: center; color: var(--vela-fg-muted); font-size: 12px; }
|
|
1525
1528
|
|
|
1526
1529
|
/* \u2500\u2500 drawing groups \u2500\u2500 */
|
|
1527
|
-
/* One top-level entry in a pane's drawing list: a lone drawing, or a whole group block.
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
+
/* One top-level entry in a pane's drawing list: a lone drawing, or a whole group block. No
|
|
1531
|
+
border of its own \u2014 units stack flush, so consecutive highlighted rows read as one block; the
|
|
1532
|
+
drop-into-group outline is drawn inside the box instead (see the drag-and-drop rules). */
|
|
1533
|
+
.vela-ot-unit { border-radius: 6px; }
|
|
1534
|
+
/* Adjacent picked rows merge into one contiguous highlight: the shared edge loses its rounding. */
|
|
1535
|
+
.vela-ot-unit:has(> .vela-ot-row[data-picked]) + .vela-ot-unit > .vela-ot-row[data-picked] { border-top-left-radius: 0; border-top-right-radius: 0; }
|
|
1536
|
+
.vela-ot-unit:has(+ .vela-ot-unit > .vela-ot-row[data-picked]) > .vela-ot-row[data-picked] { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
|
|
1530
1537
|
.vela-ot-row[data-row-kind='group'] > .vela-icon { width: 12px; font-size: 11px; }
|
|
1531
1538
|
/* A member sits indented under its group's header. */
|
|
1532
1539
|
.vela-ot-subrow { padding-left: 26px; }
|
|
@@ -1583,8 +1590,10 @@ var CSS4 = `
|
|
|
1583
1590
|
.vela-ot-gap[data-drop] { height: 4px; background: var(--vela-fg-bright); }
|
|
1584
1591
|
.vela-ot-gap[data-drop]::before { display: none; }
|
|
1585
1592
|
/* A whole container accepts the drop: merging into a pane, or a pane with no drawings yet.
|
|
1586
|
-
The pane block's transparent border reserves the room for this outline
|
|
1593
|
+
The pane block's transparent border reserves the room for this outline; a group unit has no
|
|
1594
|
+
border to color, so it draws the same line as an inset outline (no layout footprint). */
|
|
1587
1595
|
.vela-ot [data-drop='target'] { border-color: var(--vela-fg-bright); background: var(--vela-hover); }
|
|
1596
|
+
.vela-ot-unit[data-drop='target'] { outline: 1px solid var(--vela-fg-bright); outline-offset: -1px; }
|
|
1588
1597
|
/* Where a reorder would insert. */
|
|
1589
1598
|
.vela-ot [data-drop='before'] { box-shadow: inset 0 2px 0 var(--vela-fg-bright); }
|
|
1590
1599
|
.vela-ot [data-drop='after'] { box-shadow: inset 0 -2px 0 var(--vela-fg-bright); }
|
|
@@ -1647,7 +1656,8 @@ var ObjectTree = class extends SidePanel {
|
|
|
1647
1656
|
super(host, "Object tree", "vela-ot");
|
|
1648
1657
|
this.iconFor = iconFor;
|
|
1649
1658
|
this.chart = null;
|
|
1650
|
-
|
|
1659
|
+
/** What the CHART has selected — every member of a multi-selection, mirrored as rows. */
|
|
1660
|
+
this.selectedDrawings = /* @__PURE__ */ new Set();
|
|
1651
1661
|
this.symbolName = "";
|
|
1652
1662
|
/** The raw (possibly venue-prefixed) symbol — what icon resolution routes on. */
|
|
1653
1663
|
this.symbolRaw = "";
|
|
@@ -1698,12 +1708,9 @@ var ObjectTree = class extends SidePanel {
|
|
|
1698
1708
|
this.unsubs.push(chart.on(ev, () => this.refresh()));
|
|
1699
1709
|
}
|
|
1700
1710
|
this.unsubs.push(
|
|
1701
|
-
chart.on("drawing:selected", ({
|
|
1702
|
-
this.
|
|
1703
|
-
if (!this.syncingSelection)
|
|
1704
|
-
this.picked.clear();
|
|
1705
|
-
if (id) this.picked.add(id);
|
|
1706
|
-
}
|
|
1711
|
+
chart.on("drawing:selected", ({ ids }) => {
|
|
1712
|
+
this.selectedDrawings = new Set(ids);
|
|
1713
|
+
if (!this.syncingSelection) this.picked = new Set(ids);
|
|
1707
1714
|
this.refresh();
|
|
1708
1715
|
})
|
|
1709
1716
|
);
|
|
@@ -2051,7 +2058,7 @@ var ObjectTree = class extends SidePanel {
|
|
|
2051
2058
|
el.dataset.drag = "1";
|
|
2052
2059
|
el.title = "Drag to restack, or onto another pane to move it there";
|
|
2053
2060
|
if (inGroup) el.classList.add("vela-ot-subrow");
|
|
2054
|
-
if (d.id
|
|
2061
|
+
if (this.selectedDrawings.has(d.id)) el.dataset.selected = "1";
|
|
2055
2062
|
if (this.picked.has(d.id)) el.dataset.picked = "1";
|
|
2056
2063
|
el.addEventListener("click", (e) => this.onDrawClick(e, d.id));
|
|
2057
2064
|
return el;
|
|
@@ -3228,6 +3235,20 @@ var SymbolPicker = class {
|
|
|
3228
3235
|
this.seed = initialQuery;
|
|
3229
3236
|
this.dialog.show();
|
|
3230
3237
|
}
|
|
3238
|
+
get isOpen() {
|
|
3239
|
+
return this.dialog.open;
|
|
3240
|
+
}
|
|
3241
|
+
/** Text typed at the picker that never reached its field: closed, it opens seeded
|
|
3242
|
+
* with the text; open (the field takes focus a tick after the dialog does, and a
|
|
3243
|
+
* fast typist's next key lands in that tick), it extends the query. */
|
|
3244
|
+
type(text) {
|
|
3245
|
+
if (!this.isOpen) {
|
|
3246
|
+
this.open(text);
|
|
3247
|
+
return;
|
|
3248
|
+
}
|
|
3249
|
+
this.input.value = (this.input.value + text).toUpperCase();
|
|
3250
|
+
this.refresh();
|
|
3251
|
+
}
|
|
3231
3252
|
close() {
|
|
3232
3253
|
this.dialog.hide();
|
|
3233
3254
|
}
|
|
@@ -3641,6 +3662,20 @@ var TimeframeQuick = class {
|
|
|
3641
3662
|
this.input.setSelectionRange(this.input.value.length, this.input.value.length);
|
|
3642
3663
|
}, 0);
|
|
3643
3664
|
}
|
|
3665
|
+
get isOpen() {
|
|
3666
|
+
return this.dialog.open;
|
|
3667
|
+
}
|
|
3668
|
+
/** Text typed at the entry that never reached its field: closed, it opens seeded
|
|
3669
|
+
* with the text; open (the field takes focus a tick after the dialog does, and a
|
|
3670
|
+
* fast typist's next key lands in that tick), it extends the entry. */
|
|
3671
|
+
type(text) {
|
|
3672
|
+
if (!this.isOpen) {
|
|
3673
|
+
this.open(text);
|
|
3674
|
+
return;
|
|
3675
|
+
}
|
|
3676
|
+
this.input.value += text;
|
|
3677
|
+
this.renderHint();
|
|
3678
|
+
}
|
|
3644
3679
|
close() {
|
|
3645
3680
|
this.dialog.hide();
|
|
3646
3681
|
}
|
|
@@ -4033,11 +4068,34 @@ function fmtChange(open, close) {
|
|
|
4033
4068
|
const sign = diff >= 0 ? "+" : "";
|
|
4034
4069
|
return `${sign}${fmtPrice(diff, decimalsFor(close))} (${sign}${pct.toFixed(2)}%)`;
|
|
4035
4070
|
}
|
|
4071
|
+
function fmtChangePct(open, close) {
|
|
4072
|
+
if (open == null || close == null || !Number.isFinite(open) || !Number.isFinite(close) || open === 0) return "";
|
|
4073
|
+
const pct = (close - open) / open * 100;
|
|
4074
|
+
return `${pct >= 0 ? "+" : ""}${pct.toFixed(2)}%`;
|
|
4075
|
+
}
|
|
4036
4076
|
|
|
4037
4077
|
// src/widget/statusline-model.ts
|
|
4038
4078
|
function segmentVisibility(parts, chartHidden = false) {
|
|
4039
4079
|
return { avatar: parts.logo, symbol: parts.name, meta: parts.name, market: parts.market, ohlc: parts.ohlc && !chartHidden, change: parts.change && !chartHidden, eye: chartHidden };
|
|
4040
4080
|
}
|
|
4081
|
+
var STATUSLINE_LADDER = [
|
|
4082
|
+
{ stacked: false, level: "full" },
|
|
4083
|
+
{ stacked: true, level: "full" },
|
|
4084
|
+
{ stacked: true, level: "compact" },
|
|
4085
|
+
{ stacked: true, level: "minimal" }
|
|
4086
|
+
];
|
|
4087
|
+
function readoutCells(level, readout) {
|
|
4088
|
+
if (readout === "value") return [{ key: "close", label: "" }];
|
|
4089
|
+
if (level === "full") {
|
|
4090
|
+
return [
|
|
4091
|
+
{ key: "open", label: "O" },
|
|
4092
|
+
{ key: "high", label: "H" },
|
|
4093
|
+
{ key: "low", label: "L" },
|
|
4094
|
+
{ key: "close", label: "C" }
|
|
4095
|
+
];
|
|
4096
|
+
}
|
|
4097
|
+
return [{ key: "close", label: level === "compact" ? "C" : "" }];
|
|
4098
|
+
}
|
|
4041
4099
|
function statuslineMenuItems(parts, chartVisible) {
|
|
4042
4100
|
return [
|
|
4043
4101
|
{ id: "part:logo", label: "Symbol logo", checked: parts.logo },
|
|
@@ -4064,6 +4122,11 @@ var CSS10 = `
|
|
|
4064
4122
|
display: flex;
|
|
4065
4123
|
align-items: baseline;
|
|
4066
4124
|
gap: var(--vela-space-2);
|
|
4125
|
+
/* The chip never grows past the plot: fit() measures overflow against this width to
|
|
4126
|
+
* walk the layout ladder (stack, then shed values), so overflow:hidden only guards
|
|
4127
|
+
* the transient between a resize and the next measure. */
|
|
4128
|
+
max-width: calc(100% - var(--vela-toolbar-gutter, 0px) - var(--vela-scale-gutter, 0px) - 24px);
|
|
4129
|
+
overflow: hidden;
|
|
4067
4130
|
color: var(--vela-fg);
|
|
4068
4131
|
font-size: var(--vela-font-size-md);
|
|
4069
4132
|
/* Same chip treatment as the indicator legend rows (InputsUI): a translucent wash of
|
|
@@ -4085,6 +4148,31 @@ var CSS10 = `
|
|
|
4085
4148
|
/* Chart hidden (the price series' eye \u2014 renderer 'candleVisible'): the line dims to
|
|
4086
4149
|
* the same 0.5 wash a hidden indicator's legend row wears. */
|
|
4087
4150
|
.vela-statusline.vela-sl-chart-hidden { opacity: 0.5; }
|
|
4151
|
+
/* Two rows inside the chip \u2014 the identity (logo / symbol / meta / market badge) and the
|
|
4152
|
+
* value readout (O/H/L/C + change, or the show-chart eye). In the widest layout they sit
|
|
4153
|
+
* side by side on one line; the STACKED layouts (fit() decides, see the ladder in
|
|
4154
|
+
* statusline-model) turn the chip into a column so the values drop under the symbol. */
|
|
4155
|
+
.vela-statusline .vela-sl-row {
|
|
4156
|
+
display: flex;
|
|
4157
|
+
align-items: baseline;
|
|
4158
|
+
gap: var(--vela-space-2);
|
|
4159
|
+
white-space: nowrap;
|
|
4160
|
+
}
|
|
4161
|
+
.vela-statusline.vela-sl-stacked {
|
|
4162
|
+
flex-direction: column;
|
|
4163
|
+
align-items: flex-start;
|
|
4164
|
+
/* The same air between the two rows as between the values row and the legend row
|
|
4165
|
+
* that follows the chip (see the stacked legend shift below). */
|
|
4166
|
+
row-gap: var(--vela-space-1);
|
|
4167
|
+
}
|
|
4168
|
+
/* Stacked, the identity row may shrink (the meta carries the ellipsis) \u2014 the values row
|
|
4169
|
+
* never does, so its overflow is what fit() measures to keep descending the ladder. */
|
|
4170
|
+
.vela-statusline.vela-sl-stacked .vela-sl-identity { max-width: 100%; }
|
|
4171
|
+
.vela-statusline.vela-sl-stacked .vela-sl-meta {
|
|
4172
|
+
min-width: 0;
|
|
4173
|
+
overflow: hidden;
|
|
4174
|
+
text-overflow: ellipsis;
|
|
4175
|
+
}
|
|
4088
4176
|
.vela-statusline .vela-sl-avatar {
|
|
4089
4177
|
width: 18px;
|
|
4090
4178
|
height: 18px;
|
|
@@ -4136,59 +4224,13 @@ var CSS10 = `
|
|
|
4136
4224
|
* stylesheet is document-global, so a bare attribute selector here would shift every
|
|
4137
4225
|
* chart on the page, including statusline-less ones. */
|
|
4138
4226
|
.vela-has-statusline [${LEGEND_AT_TOP_ATTR}] { transform: translateY(26px); }
|
|
4139
|
-
/*
|
|
4140
|
-
*
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
*
|
|
4144
|
-
|
|
4145
|
-
[data-layout='mobile'] .vela-statusline {
|
|
4146
|
-
display: grid;
|
|
4147
|
-
grid-template-columns: auto auto minmax(0, auto) auto;
|
|
4148
|
-
justify-content: start;
|
|
4149
|
-
align-items: center;
|
|
4150
|
-
row-gap: 1px;
|
|
4151
|
-
max-width: calc(100% - var(--vela-toolbar-gutter, 0px) - var(--vela-scale-gutter, 0px) - 24px);
|
|
4152
|
-
font-size: var(--vela-font-size-sm);
|
|
4153
|
-
}
|
|
4154
|
-
[data-layout='mobile'] .vela-statusline .vela-sl-symbol {
|
|
4155
|
-
font-size: var(--vela-font-size-md);
|
|
4156
|
-
line-height: 1;
|
|
4157
|
-
}
|
|
4158
|
-
[data-layout='mobile'] .vela-statusline .vela-sl-meta {
|
|
4159
|
-
min-width: 0;
|
|
4160
|
-
overflow: hidden;
|
|
4161
|
-
text-overflow: ellipsis;
|
|
4162
|
-
white-space: nowrap;
|
|
4163
|
-
line-height: 1;
|
|
4164
|
-
}
|
|
4165
|
-
[data-layout='mobile'] .vela-statusline .vela-sl-avatar,
|
|
4166
|
-
[data-layout='mobile'] .vela-statusline .vela-sl-market { align-self: center; }
|
|
4167
|
-
[data-layout='mobile'] .vela-statusline .vela-sl-ohlc { display: none !important; }
|
|
4168
|
-
[data-layout='mobile'] .vela-statusline .vela-sl-change {
|
|
4169
|
-
/* Second row, under the text column \u2014 the avatar keeps the first column. */
|
|
4170
|
-
grid-column: 2 / -1;
|
|
4171
|
-
font-size: var(--vela-font-size-sm);
|
|
4172
|
-
line-height: 1.2;
|
|
4173
|
-
}
|
|
4174
|
-
[data-layout='mobile'] .vela-has-statusline [${LEGEND_AT_TOP_ATTR}] { transform: translateY(40px); }
|
|
4175
|
-
/* FIT mode (multi-chart cells \u2014 see setFitMode): the line never wraps; segments that
|
|
4176
|
-
* don't fit are HIDDEN by fit() (change first, then meta, then the market badge), so
|
|
4177
|
-
* overflow:hidden only guards the transient between a resize and the next measure.
|
|
4178
|
-
* Placed after the mobile block on purpose: same specificity, later wins. */
|
|
4179
|
-
.vela-statusline.vela-sl-fit {
|
|
4180
|
-
display: flex; /* undo the mobile grid \u2014 fit mode is one flex row again */
|
|
4181
|
-
flex-wrap: nowrap;
|
|
4182
|
-
align-items: center;
|
|
4183
|
-
max-width: calc(100% - var(--vela-toolbar-gutter, 0px) - var(--vela-scale-gutter, 0px) - 24px);
|
|
4184
|
-
overflow: hidden;
|
|
4185
|
-
}
|
|
4186
|
-
.vela-statusline.vela-sl-fit .vela-sl-change {
|
|
4187
|
-
flex-basis: auto;
|
|
4188
|
-
padding-left: 0;
|
|
4189
|
-
}
|
|
4190
|
-
/* One row again \u2014 the mobile two-line shift doesn't apply in fit mode. */
|
|
4191
|
-
[data-layout='mobile'] .vela-sl-fit-host.vela-has-statusline [${LEGEND_AT_TOP_ATTR}] { transform: translateY(26px); }
|
|
4227
|
+
/* A stacked chip is two lines tall \u2014 the legend shifts one more line. fit() flags the
|
|
4228
|
+
* host whenever the ladder lands on a stacked layout. */
|
|
4229
|
+
.vela-has-statusline.vela-sl-stacked-host [${LEGEND_AT_TOP_ATTR}] { transform: translateY(40px); }
|
|
4230
|
+
/* Mobile: the same ladder at the phone's type scale \u2014 the width alone decides how much
|
|
4231
|
+
* of the readout fits, exactly as on a narrow desktop chart. */
|
|
4232
|
+
[data-layout='mobile'] .vela-statusline { font-size: var(--vela-font-size-sm); }
|
|
4233
|
+
[data-layout='mobile'] .vela-statusline .vela-sl-symbol { font-size: var(--vela-font-size-md); }
|
|
4192
4234
|
`;
|
|
4193
4235
|
function baseOfTicker(ticker) {
|
|
4194
4236
|
return ticker.replace(/[-_/]?(USDT|USDC|USD1|USDS|BUSD|USD|EUR|PERP)$/i, "") || ticker;
|
|
@@ -4259,6 +4301,8 @@ var Statusline = class {
|
|
|
4259
4301
|
/** Fit mode (multi-chart cells): one row, overflowing segments hidden — see {@link setFitMode}. */
|
|
4260
4302
|
this.fitMode = false;
|
|
4261
4303
|
this.fitRO = null;
|
|
4304
|
+
/** The ladder rung currently applied — see {@link fit}. */
|
|
4305
|
+
this.layout = { stacked: false, level: "full" };
|
|
4262
4306
|
this.onContextMenu = (e) => {
|
|
4263
4307
|
if (!this.menu || !this.menuHooks) return;
|
|
4264
4308
|
e.preventDefault();
|
|
@@ -4305,8 +4349,18 @@ var Statusline = class {
|
|
|
4305
4349
|
this.menuHooks?.setChartVisible(true);
|
|
4306
4350
|
this.setChartHidden(false);
|
|
4307
4351
|
});
|
|
4308
|
-
this.
|
|
4352
|
+
this.identityRow = doc.createElement("span");
|
|
4353
|
+
this.identityRow.className = "vela-sl-row vela-sl-identity";
|
|
4354
|
+
this.identityRow.append(this.avatarEl, this.symbolEl, this.metaEl, this.marketEl);
|
|
4355
|
+
this.valuesRow = doc.createElement("span");
|
|
4356
|
+
this.valuesRow.className = "vela-sl-row vela-sl-values";
|
|
4357
|
+
this.valuesRow.append(this.ohlcEl, this.changeEl, this.eyeEl);
|
|
4358
|
+
this.el.append(this.identityRow, this.valuesRow);
|
|
4309
4359
|
host.appendChild(this.el);
|
|
4360
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
4361
|
+
this.fitRO = new ResizeObserver(() => this.fit());
|
|
4362
|
+
this.fitRO.observe(host);
|
|
4363
|
+
}
|
|
4310
4364
|
this.marketTip = new Tooltip(this.marketEl, { content: MARKET_LABELS.open, placement: "bottom" });
|
|
4311
4365
|
this.eyeTip = new Tooltip(this.eyeEl, { content: "Show chart", placement: "bottom" });
|
|
4312
4366
|
this.setMarketStatus("open");
|
|
@@ -4322,27 +4376,15 @@ var Statusline = class {
|
|
|
4322
4376
|
this.fit();
|
|
4323
4377
|
}
|
|
4324
4378
|
/**
|
|
4325
|
-
* Multi-chart cells:
|
|
4326
|
-
*
|
|
4327
|
-
*
|
|
4328
|
-
* market badge; the logo + ticker always stay.
|
|
4379
|
+
* Multi-chart cells: the same width ladder as a single chart, plus a last resort for
|
|
4380
|
+
* cells too narrow for even its bottom rung — whatever still overflows is hidden
|
|
4381
|
+
* outright rather than clipped mid-glyph, least important first: the values, the
|
|
4382
|
+
* venue/timeframe meta, then the market badge; the logo + ticker always stay.
|
|
4329
4383
|
*/
|
|
4330
4384
|
setFitMode(on) {
|
|
4331
4385
|
if (on === this.fitMode) return;
|
|
4332
4386
|
this.fitMode = on;
|
|
4333
|
-
this.
|
|
4334
|
-
this.host.classList.toggle("vela-sl-fit-host", on);
|
|
4335
|
-
if (on) {
|
|
4336
|
-
if (typeof ResizeObserver !== "undefined" && !this.fitRO) {
|
|
4337
|
-
this.fitRO = new ResizeObserver(() => this.fit());
|
|
4338
|
-
this.fitRO.observe(this.host);
|
|
4339
|
-
}
|
|
4340
|
-
this.fit();
|
|
4341
|
-
} else {
|
|
4342
|
-
this.fitRO?.disconnect();
|
|
4343
|
-
this.fitRO = null;
|
|
4344
|
-
this.syncParts();
|
|
4345
|
-
}
|
|
4387
|
+
this.fit();
|
|
4346
4388
|
}
|
|
4347
4389
|
/** Project the parts config onto the segments (the baseline fit() prunes from). */
|
|
4348
4390
|
syncParts() {
|
|
@@ -4354,22 +4396,42 @@ var Statusline = class {
|
|
|
4354
4396
|
this.ohlcEl.style.display = seg.ohlc ? "" : "none";
|
|
4355
4397
|
this.changeEl.style.display = seg.change ? "" : "none";
|
|
4356
4398
|
this.eyeEl.style.display = seg.eye ? "inline-flex" : "none";
|
|
4399
|
+
this.valuesRow.style.display = seg.ohlc || seg.change || seg.eye ? "" : "none";
|
|
4400
|
+
}
|
|
4401
|
+
/** Apply one ladder rung: the stacked/inline shape and the readout's level. */
|
|
4402
|
+
applyLayout(layout) {
|
|
4403
|
+
this.layout = layout;
|
|
4404
|
+
this.el.classList.toggle("vela-sl-stacked", layout.stacked);
|
|
4405
|
+
this.host.classList.toggle("vela-sl-stacked-host", layout.stacked);
|
|
4406
|
+
this.renderValues();
|
|
4357
4407
|
}
|
|
4358
|
-
/**
|
|
4408
|
+
/**
|
|
4409
|
+
* Walk the width ladder (see {@link STATUSLINE_LADDER}) until the chip fits its
|
|
4410
|
+
* max-width: the full one-line readout, then the values stacked under the symbol
|
|
4411
|
+
* line, then O/H/L shed, then the absolute change. In fit mode, when the last rung
|
|
4412
|
+
* still overflows, whole segments hide, least important first. Without layout
|
|
4413
|
+
* (detached host, node tests) nothing overflows, so the widest rung stays.
|
|
4414
|
+
*/
|
|
4359
4415
|
fit() {
|
|
4360
|
-
if (!this.fitMode) return;
|
|
4361
4416
|
this.syncParts();
|
|
4362
4417
|
const seg = segmentVisibility(this.parts, this.chartHidden);
|
|
4418
|
+
const overflows = () => this.el.scrollWidth > this.el.clientWidth;
|
|
4419
|
+
const hasValues = seg.ohlc || seg.change;
|
|
4420
|
+
for (const rung of STATUSLINE_LADDER) {
|
|
4421
|
+
this.applyLayout(rung);
|
|
4422
|
+
if (!hasValues || !overflows()) break;
|
|
4423
|
+
}
|
|
4424
|
+
if (!this.fitMode) return;
|
|
4363
4425
|
const order = [
|
|
4364
|
-
[this.
|
|
4365
|
-
[this.changeEl, seg.change],
|
|
4426
|
+
[this.valuesRow, hasValues],
|
|
4366
4427
|
[this.metaEl, seg.meta],
|
|
4367
4428
|
[this.marketEl, seg.market]
|
|
4368
4429
|
];
|
|
4369
4430
|
for (const [el, shown] of order) {
|
|
4370
|
-
if (
|
|
4431
|
+
if (!overflows()) break;
|
|
4371
4432
|
if (shown) el.style.display = "none";
|
|
4372
4433
|
}
|
|
4434
|
+
if (this.valuesRow.style.display === "none") this.applyLayout({ ...this.layout, stacked: false });
|
|
4373
4435
|
}
|
|
4374
4436
|
/** Shape + color the value readout after the active price style: its own up/down
|
|
4375
4437
|
* colors (candle bodies, bar ticks, the line color, …), the direction rule that
|
|
@@ -4482,7 +4544,7 @@ var Statusline = class {
|
|
|
4482
4544
|
this.marketTip.destroy();
|
|
4483
4545
|
this.eyeTip.destroy();
|
|
4484
4546
|
this.marketBubble.destroy();
|
|
4485
|
-
this.host.classList.remove("vela-has-statusline", "vela-sl-
|
|
4547
|
+
this.host.classList.remove("vela-has-statusline", "vela-sl-stacked-host");
|
|
4486
4548
|
this.el.remove();
|
|
4487
4549
|
}
|
|
4488
4550
|
detach() {
|
|
@@ -4491,6 +4553,10 @@ var Statusline = class {
|
|
|
4491
4553
|
}
|
|
4492
4554
|
render() {
|
|
4493
4555
|
if (this.menuHooks) this.setChartHidden(!this.menuHooks.chartVisible());
|
|
4556
|
+
this.fit();
|
|
4557
|
+
}
|
|
4558
|
+
/** Write the value readout for the current bar at the current ladder level. */
|
|
4559
|
+
renderValues() {
|
|
4494
4560
|
const bar = this.hoverBar ?? this.lastBar;
|
|
4495
4561
|
if (!bar) {
|
|
4496
4562
|
this.ohlcEl.replaceChildren();
|
|
@@ -4510,12 +4576,11 @@ var Statusline = class {
|
|
|
4510
4576
|
s.appendChild(b);
|
|
4511
4577
|
return s;
|
|
4512
4578
|
};
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
this.changeEl.textContent = fmtChange(bar.open, bar.close);
|
|
4579
|
+
const { level } = this.layout;
|
|
4580
|
+
this.ohlcEl.replaceChildren(...readoutCells(level, this.readout).map((c) => cell(c.label, bar[c.key])));
|
|
4581
|
+
this.changeEl.textContent = level === "minimal" ? fmtChangePct(bar.open, bar.close) : fmtChange(bar.open, bar.close);
|
|
4516
4582
|
this.changeEl.dataset.dir = up ? "up" : "down";
|
|
4517
4583
|
this.changeEl.style.color = ink;
|
|
4518
|
-
this.fit();
|
|
4519
4584
|
}
|
|
4520
4585
|
};
|
|
4521
4586
|
|
|
@@ -4826,9 +4891,6 @@ var ChartContextMenu = class {
|
|
|
4826
4891
|
}
|
|
4827
4892
|
};
|
|
4828
4893
|
|
|
4829
|
-
// src/core/options.ts
|
|
4830
|
-
var normalizeSession = (v) => v === "regular" || v === "extended" ? v : void 0;
|
|
4831
|
-
|
|
4832
4894
|
// src/widget/session-shading.ts
|
|
4833
4895
|
var DAY_MS = 864e5;
|
|
4834
4896
|
var MINUTE_MS = 6e4;
|
|
@@ -8056,6 +8118,17 @@ function nextAutoCellId(taken) {
|
|
|
8056
8118
|
if (!taken.has(`c${i}`)) return `c${i}`;
|
|
8057
8119
|
}
|
|
8058
8120
|
}
|
|
8121
|
+
function resolveTyping(key, open) {
|
|
8122
|
+
if (open.dialogs > 0) {
|
|
8123
|
+
if (key.length !== 1) return null;
|
|
8124
|
+
if (open.symbolSearch) return { target: "symbol", text: key.toUpperCase() };
|
|
8125
|
+
if (open.timeframeEntry) return { target: "timeframe", text: key };
|
|
8126
|
+
return null;
|
|
8127
|
+
}
|
|
8128
|
+
if (/^[a-zA-Z]$/.test(key)) return { target: "symbol", text: key.toUpperCase() };
|
|
8129
|
+
if (/^[0-9]$/.test(key)) return { target: "timeframe", text: key };
|
|
8130
|
+
return null;
|
|
8131
|
+
}
|
|
8059
8132
|
var VelaWorkspace = class {
|
|
8060
8133
|
constructor(container, opts = {}) {
|
|
8061
8134
|
this.events = new TypedEventBus();
|
|
@@ -9689,17 +9762,14 @@ var VelaWorkspace = class {
|
|
|
9689
9762
|
}
|
|
9690
9763
|
/** Bare-typing router: letters → symbol search (seeded), digits → timeframe entry. */
|
|
9691
9764
|
routeTyping(ev) {
|
|
9692
|
-
if (this.destroyed
|
|
9765
|
+
if (this.destroyed) return;
|
|
9693
9766
|
if (ev.ctrlKey || ev.metaKey || ev.altKey) return;
|
|
9694
9767
|
if (isEditableTarget(ev)) return;
|
|
9695
|
-
const
|
|
9696
|
-
if (
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
ev.preventDefault();
|
|
9701
|
-
this.tfQuick.open(key);
|
|
9702
|
-
}
|
|
9768
|
+
const hit = resolveTyping(ev.key, { dialogs: this.openDialogs, symbolSearch: this.symbolPicker.isOpen, timeframeEntry: this.tfQuick.isOpen });
|
|
9769
|
+
if (!hit) return;
|
|
9770
|
+
ev.preventDefault();
|
|
9771
|
+
if (hit.target === "symbol") this.symbolPicker.type(hit.text);
|
|
9772
|
+
else this.tfQuick.type(hit.text);
|
|
9703
9773
|
}
|
|
9704
9774
|
trackDialog(open) {
|
|
9705
9775
|
this.openDialogs = Math.max(0, this.openDialogs + (open ? 1 : -1));
|
|
@@ -151,6 +151,7 @@ registerIcon("star-filled", S('<path d="M8 2.2l1.75 3.55 3.9.55-2.8 2.75.65 3.9L
|
|
|
151
151
|
registerIcon("grip", S('<circle cx="6" cy="3.5" r="1"/><circle cx="10" cy="3.5" r="1"/><circle cx="6" cy="8" r="1"/><circle cx="10" cy="8" r="1"/><circle cx="6" cy="12.5" r="1"/><circle cx="10" cy="12.5" r="1"/>', 'fill="currentColor" stroke="none"'));
|
|
152
152
|
registerIcon("kebab", S('<circle cx="8" cy="3.2" r="1.2"/><circle cx="8" cy="8" r="1.2"/><circle cx="8" cy="12.8" r="1.2"/>', 'fill="currentColor" stroke="none"'));
|
|
153
153
|
registerIcon("burger", S('<path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11"/>'));
|
|
154
|
+
registerIcon("info", S('<path d="M8 7.4v4.4"/><circle cx="8" cy="4.6" r="0.9" fill="currentColor" stroke="none"/>'));
|
|
154
155
|
registerIcon("reset", S('<path d="M2 8a6 6 0 1 0 6-6 6.5 6.5 0 0 0-4.5 1.83L2 5.33"/><path d="M2 2v3.33h3.33"/>'));
|
|
155
156
|
registerIcon("pane-collapse", S('<path d="M2.6 9.4h4v4M13.4 6.6h-4v-4"/><path d="m9.4 6.6 4.2-4.2M2.4 13.6l4.2-4.2"/>'));
|
|
156
157
|
registerIcon("pane-expand", S('<path d="M9.8 2.4h3.8v3.8M6.2 13.6H2.4V9.8"/><path d="m13.6 2.4-4.4 4.4M2.4 13.6l4.4-4.4"/>'));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { svg24, NEUTRAL, BEARISH, WARNING, BULLISH, INFO, ACCENT_BRIGHT, VALID, INVALID, MARKER, ACCENT, injectStyles, iconEl } from './chunk-
|
|
1
|
+
import { svg24, NEUTRAL, BEARISH, WARNING, BULLISH, INFO, ACCENT_BRIGHT, VALID, INVALID, MARKER, ACCENT, injectStyles, iconEl } from './chunk-CAFCLMPF.js';
|
|
2
2
|
|
|
3
3
|
// src/core/native-indicators/NativeIndicator.ts
|
|
4
4
|
var REGISTRY = /* @__PURE__ */ new Map();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { overlayScrollbarCss, injectStyles, isDarkColor, mix, HIGHLIGHT, ACCENT_BRIGHT, ACCENT, withAlpha, iconAt, iconEl, BULLISH, BEARISH, WARNING, NEUTRAL } from './chunk-
|
|
1
|
+
import { overlayScrollbarCss, injectStyles, isDarkColor, mix, HIGHLIGHT, ACCENT_BRIGHT, ACCENT, withAlpha, iconAt, iconEl, BULLISH, BEARISH, WARNING, NEUTRAL } from './chunk-CAFCLMPF.js';
|
|
2
2
|
import { VanillaMachine, normalizeProps, spreadProps } from '@zag-js/vanilla';
|
|
3
3
|
export { normalizeProps, spreadProps } from '@zag-js/vanilla';
|
|
4
4
|
import * as menu from '@zag-js/menu';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { normalizeProps, nextUid, runMachine, spreadProps } from './chunk-
|
|
2
|
-
import { injectStyles } from './chunk-
|
|
1
|
+
import { normalizeProps, nextUid, runMachine, spreadProps } from './chunk-T5Z5YUCF.js';
|
|
2
|
+
import { injectStyles } from './chunk-CAFCLMPF.js';
|
|
3
3
|
import * as tooltip from '@zag-js/tooltip';
|
|
4
4
|
import * as dialog from '@zag-js/dialog';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { u as Millis,
|
|
2
|
-
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-
|
|
1
|
+
import { u as Millis, aj as InputSchema, ah as IndicatorMeta, P as PriceStyle, O as OHLCV, I as InputValue, l as IndicatorModel, k as MoveTarget, av as PaneAxis, aI as SeriesSpec, af as Fill, B as Background, aA as PriceLine, a2 as DrawingLine, _ as DrawingBox, a1 as DrawingLabel, a6 as DrawingPolyline, a3 as DrawingLinefill, ab as DrawingTable, h as IndicatorStatus, a as VisibleRange, c as VelaTheme, S as SerializedDrawing, w as DrawingTypeKey, v as SnapMode, a4 as DrawingMode, e as IChartRenderer, R as RendererCapabilities, o as LegendActionView, p as LegendCalloutView, U as Unsubscribe, C as CrosshairEvent, A as AxisLongPressEvent, s as DataWindowReadout, n as SymbolPickerFn, aX as PaneInfo, ae as DrawingsOption, a8 as DrawingSeriesGateway, D as Drawing, b as VelaOptions, y as AddIndicatorOptions, au as MarketSwitch, at as MarketSnapshot, V as VisibleRangePreset, T as ThemeName } from './options-BCRmYALw.js';
|
|
2
|
+
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-Cb-2lC5O.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A strategy's broker state at ONE bar — the flat summary a host reads while a script
|
|
@@ -492,7 +492,8 @@ interface NativeIndicatorDescriptor {
|
|
|
492
492
|
/** Full display name (picker, settings header, handle title). */
|
|
493
493
|
readonly title: string;
|
|
494
494
|
/**
|
|
495
|
-
* Compact name for the on-chart legend chip
|
|
495
|
+
* Compact name for the on-chart legend chip, the settings-dialog header and the
|
|
496
|
+
* object tree's indicator rows.
|
|
496
497
|
* Absent ⇒ {@link title}. The picker keeps the full title either way.
|
|
497
498
|
*/
|
|
498
499
|
readonly shortTitle?: string;
|
|
@@ -734,9 +735,11 @@ interface VelaEventMap extends Record<string, unknown> {
|
|
|
734
735
|
"drawing:edited": {
|
|
735
736
|
id: string;
|
|
736
737
|
};
|
|
737
|
-
/** Selection changed
|
|
738
|
+
/** Selection changed. `ids` is every selected drawing in selection order; `id` is the
|
|
739
|
+
* primary (`ids[0]`, the one a settings popup edits), null when nothing is selected. */
|
|
738
740
|
"drawing:selected": {
|
|
739
741
|
id: string | null;
|
|
742
|
+
ids: string[];
|
|
740
743
|
};
|
|
741
744
|
/** The favorite-tool set changed (star toggles or a bulk restore). */
|
|
742
745
|
"drawing:favorites": {
|
|
@@ -1197,6 +1200,8 @@ declare class DrawingController {
|
|
|
1197
1200
|
destroy(): void;
|
|
1198
1201
|
/** Set/extend the selection. `additive` toggles membership (shift-click) vs replacing it. */
|
|
1199
1202
|
private setSelection;
|
|
1203
|
+
/** Push the selection to the renderer and announce it (primary + the full list). */
|
|
1204
|
+
private announceSelection;
|
|
1200
1205
|
/** Restore a history snapshot, reconciling selection against what survived. */
|
|
1201
1206
|
private restoreSnapshot;
|
|
1202
1207
|
/** Delete drawings as one undo step; prune them from the selection. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { u as Millis,
|
|
2
|
-
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-
|
|
1
|
+
import { u as Millis, aj as InputSchema, ah as IndicatorMeta, P as PriceStyle, O as OHLCV, I as InputValue, l as IndicatorModel, k as MoveTarget, av as PaneAxis, aI as SeriesSpec, af as Fill, B as Background, aA as PriceLine, a2 as DrawingLine, _ as DrawingBox, a1 as DrawingLabel, a6 as DrawingPolyline, a3 as DrawingLinefill, ab as DrawingTable, h as IndicatorStatus, a as VisibleRange, c as VelaTheme, S as SerializedDrawing, w as DrawingTypeKey, v as SnapMode, a4 as DrawingMode, e as IChartRenderer, R as RendererCapabilities, o as LegendActionView, p as LegendCalloutView, U as Unsubscribe, C as CrosshairEvent, A as AxisLongPressEvent, s as DataWindowReadout, n as SymbolPickerFn, aX as PaneInfo, ae as DrawingsOption, a8 as DrawingSeriesGateway, D as Drawing, b as VelaOptions, y as AddIndicatorOptions, au as MarketSwitch, at as MarketSnapshot, V as VisibleRangePreset, T as ThemeName } from './options-BCRmYALw.cjs';
|
|
2
|
+
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-UtWw2CgJ.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A strategy's broker state at ONE bar — the flat summary a host reads while a script
|
|
@@ -492,7 +492,8 @@ interface NativeIndicatorDescriptor {
|
|
|
492
492
|
/** Full display name (picker, settings header, handle title). */
|
|
493
493
|
readonly title: string;
|
|
494
494
|
/**
|
|
495
|
-
* Compact name for the on-chart legend chip
|
|
495
|
+
* Compact name for the on-chart legend chip, the settings-dialog header and the
|
|
496
|
+
* object tree's indicator rows.
|
|
496
497
|
* Absent ⇒ {@link title}. The picker keeps the full title either way.
|
|
497
498
|
*/
|
|
498
499
|
readonly shortTitle?: string;
|
|
@@ -734,9 +735,11 @@ interface VelaEventMap extends Record<string, unknown> {
|
|
|
734
735
|
"drawing:edited": {
|
|
735
736
|
id: string;
|
|
736
737
|
};
|
|
737
|
-
/** Selection changed
|
|
738
|
+
/** Selection changed. `ids` is every selected drawing in selection order; `id` is the
|
|
739
|
+
* primary (`ids[0]`, the one a settings popup edits), null when nothing is selected. */
|
|
738
740
|
"drawing:selected": {
|
|
739
741
|
id: string | null;
|
|
742
|
+
ids: string[];
|
|
740
743
|
};
|
|
741
744
|
/** The favorite-tool set changed (star toggles or a bulk restore). */
|
|
742
745
|
"drawing:favorites": {
|
|
@@ -1197,6 +1200,8 @@ declare class DrawingController {
|
|
|
1197
1200
|
destroy(): void;
|
|
1198
1201
|
/** Set/extend the selection. `additive` toggles membership (shift-click) vs replacing it. */
|
|
1199
1202
|
private setSelection;
|
|
1203
|
+
/** Push the selection to the renderer and announce it (primary + the full list). */
|
|
1204
|
+
private announceSelection;
|
|
1200
1205
|
/** Restore a history snapshot, reconciling selection against what survived. */
|
|
1201
1206
|
private restoreSnapshot;
|
|
1202
1207
|
/** Delete drawings as one undo step; prune them from the selection. */
|