@luxalgo/vela 0.5.2 → 0.5.3

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.
@@ -1,5 +1,5 @@
1
- import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel } from './chunk-RRFGWZNJ.js';
2
- import { chartType, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, getDrawingType } from './chunk-B5TIKQJ5.js';
1
+ import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel } from './chunk-L5NTMWPP.js';
2
+ import { chartType, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, getDrawingType } from './chunk-WJKLBYRM.js';
3
3
  import { Tooltip, Menu, Dialog, Drawer } from './chunk-P556H6EA.js';
4
4
  import { iconMarkup, registerIcon, injectStyles, iconEl, SESSION_PRE, SESSION_POST, SESSION_OFF, icon, categoricalColor } from './chunk-LJLZR44Y.js';
5
5
 
@@ -1216,17 +1216,17 @@ var STYLE_ID4 = "vela-widget-watermark";
1216
1216
  var CSS4 = `
1217
1217
  .vela-watermark {
1218
1218
  position: absolute;
1219
- /* Insets follow the renderer-published gutters (mount container), so the mark
1220
- * centers and fits within the PLOT \u2014 never bleeding into the drawings toolbar
1221
- * on the left or the price scale on the right (visible in small multi-chart
1222
- * cells, where the scale is a large share of the width). */
1223
- top: 0;
1224
- bottom: 0;
1219
+ /* Insets follow the renderer-published gutters AND the price-pane vertical
1220
+ * bounds (mount container), so the mark centers on the PRICE PANE \u2014 never
1221
+ * the study panes below, the drawings toolbar, or the price scale. */
1222
+ top: var(--vela-price-pane-top, 0px);
1223
+ bottom: var(--vela-price-pane-bottom, 0px);
1225
1224
  left: var(--vela-toolbar-gutter, 0px);
1226
1225
  right: var(--vela-scale-gutter, 0px);
1227
1226
  display: flex;
1228
1227
  align-items: center;
1229
1228
  justify-content: center;
1229
+ overflow: hidden;
1230
1230
  pointer-events: none;
1231
1231
  z-index: 1;
1232
1232
  color: var(--vela-fg);
@@ -1281,7 +1281,7 @@ var Watermark = class {
1281
1281
  this.text.textContent = symbol ? `${parseSymbol(symbol).ticker} \xB7 ${timeframeLabel(timeframe)}` : "";
1282
1282
  this.fit();
1283
1283
  }
1284
- /** Measure the text at the cap and shrink it to the chart's own width. */
1284
+ /** Measure the text at the cap and shrink it to the price pane's width. */
1285
1285
  fit() {
1286
1286
  if (this.el.clientWidth <= 0 || !this.text.textContent) return;
1287
1287
  this.el.style.fontSize = `${MAX_FONT_PX}px`;
@@ -1,4 +1,4 @@
1
- import { deserializeDrawing, chartTypes, rendererLayers, registerChartType, rendererDefaults, getDrawingType, settingsRowVisible, normalizeSettingsRow, TextLabel, Callout, resetDrawingSettings, registerNativeIndicator, chartType, getNativeIndicator, nativeIndicatorDescriptors, drawingTypes, settingsRowValueKeys, formatDuration, RegressionChannel, FixedRangeVolumeProfile, SegmentDrawing, ArrowMark, GlyphStamp, RadialFib, FibSpiral, DedekindTessellation, MachFigure, GannSquare, FibRatios, MeasureBox, PositionTool, AnchoredVwap, PatternDrawing, Comment, PriceNote, Signpost, Note, PriceLabel, GANN_SQUARE_ARCS, lineSegmentIntersection, DEFAULT_DRAWING_COLOR, GLYPH_OPTIONS, STAMP_SIZE_OPTIONS, LINE_STYLE_OPTIONS, DEDEKIND_CURVATURE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, TEXT_SIZE_OPTIONS, createDrawing, tickerModifierIds, CalloutBase, DIRECTION_OPTIONS } from './chunk-B5TIKQJ5.js';
1
+ import { deserializeDrawing, chartTypes, rendererLayers, foldBaseModulation, registerChartType, rendererDefaults, getDrawingType, settingsRowVisible, normalizeSettingsRow, TextLabel, Callout, resetDrawingSettings, registerNativeIndicator, chartType, getNativeIndicator, nativeIndicatorDescriptors, drawingTypes, settingsRowValueKeys, formatDuration, RegressionChannel, FixedRangeVolumeProfile, SegmentDrawing, ArrowMark, GlyphStamp, RadialFib, FibSpiral, DedekindTessellation, MachFigure, GannSquare, FibRatios, MeasureBox, PositionTool, AnchoredVwap, PatternDrawing, Comment, PriceNote, Signpost, Note, PriceLabel, GANN_SQUARE_ARCS, lineSegmentIntersection, DEFAULT_DRAWING_COLOR, GLYPH_OPTIONS, STAMP_SIZE_OPTIONS, LINE_STYLE_OPTIONS, DEDEKIND_CURVATURE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, TEXT_SIZE_OPTIONS, createDrawing, tickerModifierIds, CalloutBase, DIRECTION_OPTIONS } from './chunk-WJKLBYRM.js';
2
2
  import { themeTokens, STATIC_TOKENS } from './chunk-ATPU5CI6.js';
3
3
  import { icon, iconAt, withAlpha, NEUTRAL, BEARISH, BULLISH, isDarkColor, toHex6, ACCENT, SERIES_LINE, SLATE, CROSSHAIR, TRADE_EXIT, TRADE_SHORT, TRADE_LONG, SLATE_DEEP, VALID, INVALID, svg24, WARNING, svg24Solid } from './chunk-LJLZR44Y.js';
4
4
 
@@ -6969,7 +6969,7 @@ var TOUCH_TAP_SLOP = 14;
6969
6969
  var DOUBLE_TAP_MS = 350;
6970
6970
  var DOUBLE_TAP_SLOP = 30;
6971
6971
  var TIME_SCALE_K = 4e-3;
6972
- var WHEEL_ZOOM_K = 25e-4;
6972
+ var WHEEL_ZOOM_K = 4e-3;
6973
6973
  function wheelZoomAnchor(coords, cursorX, rightEdge) {
6974
6974
  if (rightEdge) return { logical: coords.rightEdgeLogical, x: coords.width };
6975
6975
  return { logical: coords.xToLogical(cursorX), x: cursorX };
@@ -7023,6 +7023,8 @@ var InputController = class {
7023
7023
  // smoothed pointer velocity, px/ms
7024
7024
  this.middleDeleted = false;
7025
7025
  // the last middle press deleted a drawing (suppress autoscroll/paste)
7026
+ this.rightCancelled = false;
7027
+ // the last right press cancelled a placement (suppress the context menu)
7026
7028
  // Last cursor position over the element (NaN once it leaves) — lets a modifier
7027
7029
  // press/release re-shape the drawings preview with the pointer stationary.
7028
7030
  this.cursorX = NaN;
@@ -7047,6 +7049,14 @@ var InputController = class {
7047
7049
  this.onMiddleGuard = (e) => {
7048
7050
  if (e.button === 1 && this.middleDeleted) e.preventDefault();
7049
7051
  };
7052
+ /** A right press that cancelled a placement must not ALSO open the host's chart
7053
+ * context menu — swallow its companion event before it bubbles to the host. */
7054
+ this.onContextGuard = (e) => {
7055
+ if (!this.rightCancelled) return;
7056
+ this.rightCancelled = false;
7057
+ e.preventDefault();
7058
+ e.stopPropagation();
7059
+ };
7050
7060
  /** A modifier press/release with the pointer stationary: re-issue the last cursor
7051
7061
  * position so the placing ghost / drag preview reflects the new state immediately
7052
7062
  * (Shift's 45° angle lock, Ctrl/Cmd's momentary strong magnet). */
@@ -7063,6 +7073,11 @@ var InputController = class {
7063
7073
  if (this.middleDeleted) e.preventDefault();
7064
7074
  return;
7065
7075
  }
7076
+ if (e.button === 2) {
7077
+ this.rightCancelled = this.deps.drawingsCancelPlacement?.() ?? false;
7078
+ if (this.rightCancelled) e.preventDefault();
7079
+ return;
7080
+ }
7066
7081
  if (e.button !== 0) return;
7067
7082
  const { x, y } = this.local(e);
7068
7083
  if (e.pointerType === "touch") {
@@ -7267,6 +7282,7 @@ var InputController = class {
7267
7282
  el.addEventListener("wheel", this.onWheel, { passive: false });
7268
7283
  el.addEventListener("mousedown", this.onMiddleGuard);
7269
7284
  el.addEventListener("auxclick", this.onMiddleGuard);
7285
+ el.addEventListener("contextmenu", this.onContextGuard);
7270
7286
  const win = el.ownerDocument?.defaultView;
7271
7287
  win?.addEventListener("keydown", this.onModifier);
7272
7288
  win?.addEventListener("keyup", this.onModifier);
@@ -7288,6 +7304,7 @@ var InputController = class {
7288
7304
  el.removeEventListener("wheel", this.onWheel);
7289
7305
  el.removeEventListener("mousedown", this.onMiddleGuard);
7290
7306
  el.removeEventListener("auxclick", this.onMiddleGuard);
7307
+ el.removeEventListener("contextmenu", this.onContextGuard);
7291
7308
  this.cancelLongPress();
7292
7309
  this.touches.clear();
7293
7310
  this.el = null;
@@ -8960,8 +8977,11 @@ var ChromeRenderer = class {
8960
8977
  }
8961
8978
  ctx.font = `${scene.style.fontSize}px ${theme.fontFamily}`;
8962
8979
  ctx.textBaseline = "middle";
8963
- if (coords.barCount === 0) return;
8964
8980
  const panes = scene.orderedPanes();
8981
+ if (coords.barCount === 0) {
8982
+ this.drawPaneSeparators(ctx, scene, theme, fullW, panes);
8983
+ return;
8984
+ }
8965
8985
  const pricePane = panes.find((p) => p.kind === "price") ?? null;
8966
8986
  for (const pane of panes) {
8967
8987
  if (pane.collapsed) continue;
@@ -14405,6 +14425,16 @@ var UserDrawingController = class {
14405
14425
  if (this.eraserMode) return "pointer";
14406
14426
  return this.interaction.cursorAt(x, y);
14407
14427
  }
14428
+ /** Right-click while placing: cancel the in-progress drawing and revert to the
14429
+ * pointer — the gesture is an explicit escape, so it disarms even in
14430
+ * stay-in-drawing-mode (where Escape would leave the tool armed). Returns whether
14431
+ * the press was consumed; false lets the host's context menu open normally. */
14432
+ cancelPlacement() {
14433
+ if (!this.interaction.isPlacing()) return false;
14434
+ this.interaction.cancel();
14435
+ if (this.activeTool != null) this.emit({ kind: "arm", type: null });
14436
+ return true;
14437
+ }
14408
14438
  /** Double-click over a drawing → suppress the chart's view reset (single-click already
14409
14439
  * opens settings). Returns true only when a drawing is under the cursor. */
14410
14440
  dblClick(x, y) {
@@ -15520,7 +15550,7 @@ var NativeRenderer = class {
15520
15550
  this.scrollTargetRO = null;
15521
15551
  // eased rightOffset target while gliding back to the latest bars
15522
15552
  // Distance (px) from the plot's bottom edge to the button — tracks the bottom-most EXPANDED
15523
- // pane like the watermark: when the lower sub-panes collapse it rides up into the open pane.
15553
+ // pane: when the lower sub-panes collapse it rides up into the open pane.
15524
15554
  this.scrollBtnBottomPx = SCROLL_BTN_BOTTOM;
15525
15555
  // Distance (px) from the plot's right edge — clears the FULL scale gutter, which widens when a
15526
15556
  // pane carries merged (own-scale) columns; the constant only clears a single-column scale.
@@ -16487,6 +16517,7 @@ var NativeRenderer = class {
16487
16517
  drawingsClaim: (x, y) => this.userDrawings?.claim(x, y) ?? false,
16488
16518
  drawingsMeasureStart: (x, y) => this.userDrawings?.beginMeasureAt(x, y) ?? false,
16489
16519
  drawingsDeleteAt: (x, y) => this.userDrawings?.deleteAt(x, y) ?? false,
16520
+ drawingsCancelPlacement: () => this.userDrawings?.cancelPlacement() ?? false,
16490
16521
  drawingsSnapMode: () => this.snapMode,
16491
16522
  drawingsPointerDown: (x, y, snap, shift) => this.userDrawings?.pointerDown(x, y, snap, shift),
16492
16523
  drawingsPointerMove: (x, y, snap, shift) => this.userDrawings?.pointerMove(x, y, snap, shift),
@@ -16738,6 +16769,8 @@ var NativeRenderer = class {
16738
16769
  this.attributionEl = null;
16739
16770
  this.mountContainer?.style.removeProperty("--vela-toolbar-gutter");
16740
16771
  this.mountContainer?.style.removeProperty("--vela-scale-gutter");
16772
+ this.mountContainer?.style.removeProperty("--vela-price-pane-top");
16773
+ this.mountContainer?.style.removeProperty("--vela-price-pane-bottom");
16741
16774
  this.mountContainer = null;
16742
16775
  this.wrapper?.remove();
16743
16776
  }
@@ -17827,19 +17860,18 @@ var NativeRenderer = class {
17827
17860
  theme: this.theme
17828
17861
  });
17829
17862
  const nowMs = typeof performance !== "undefined" ? performance.now() : Date.now();
17863
+ let folded = null;
17830
17864
  for (const l of this.extLayers) {
17831
17865
  const args = this.extLayerArgs(l.def.id, pane.scale, pane.bounds, nowMs);
17832
17866
  l.instance.render(args);
17833
- if (l.def.id === this.scene.priceStyle && l.instance.modulateBase) {
17834
- const mod = l.instance.modulateBase(args);
17835
- if (mod) {
17836
- if (mod.candleBodyScale != null) this.backend.candleBodyScale = clamp012(mod.candleBodyScale) || 0.01;
17837
- if (mod.candleBodyAlpha != null) this.backend.candleBodyAlpha = clamp012(mod.candleBodyAlpha) * this.candleBodyAlpha;
17838
- if (mod.gridAlpha != null) this.backend.gridAlpha = clamp012(mod.gridAlpha);
17839
- }
17840
- }
17867
+ folded = foldBaseModulation(folded, l.instance.modulateBase?.(args) ?? null);
17841
17868
  if (this.animZoom && l.instance.animating?.()) this.animator.start();
17842
17869
  }
17870
+ if (folded) {
17871
+ if (folded.candleBodyScale != null) this.backend.candleBodyScale = clamp012(folded.candleBodyScale) || 0.01;
17872
+ if (folded.candleBodyAlpha != null) this.backend.candleBodyAlpha = clamp012(folded.candleBodyAlpha) * this.candleBodyAlpha;
17873
+ if (folded.gridAlpha != null) this.backend.gridAlpha = clamp012(folded.gridAlpha);
17874
+ }
17843
17875
  }
17844
17876
  const li = this.bars.length - 1;
17845
17877
  const liveActual = li >= 0 ? this.bars[li] : void 0;
@@ -18231,6 +18263,7 @@ var NativeRenderer = class {
18231
18263
  this.paneControls?.reposition();
18232
18264
  this.repositionScrollButton();
18233
18265
  this.positionAttribution();
18266
+ this.publishPricePaneBounds();
18234
18267
  return;
18235
18268
  }
18236
18269
  const collapsed = panes.filter((p) => p.collapsed);
@@ -18248,9 +18281,10 @@ var NativeRenderer = class {
18248
18281
  this.paneControls?.reposition();
18249
18282
  this.repositionScrollButton();
18250
18283
  this.positionAttribution();
18284
+ this.publishPricePaneBounds();
18251
18285
  }
18252
- /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area (like the
18253
- * watermark): with all lower sub-panes collapsed it settles into the lowest open pane. */
18286
+ /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area:
18287
+ * with all lower sub-panes collapsed it settles into the lowest open pane. */
18254
18288
  repositionScrollButton() {
18255
18289
  const dataHeight = this.coords.height;
18256
18290
  if (dataHeight <= 0) return;
@@ -18294,6 +18328,21 @@ var NativeRenderer = class {
18294
18328
  this.mountContainer?.style.setProperty("--vela-toolbar-gutter", `${this.toolbarGutter}px`);
18295
18329
  this.mountContainer?.style.setProperty("--vela-scale-gutter", `${this.rightAxisW}px`);
18296
18330
  }
18331
+ /** Publish the price pane's vertical insets as `--vela-price-pane-top` /
18332
+ * `--vela-price-pane-bottom` on the mount container, so the symbol watermark
18333
+ * (and any other host overlay) can clip to the price pane instead of spanning
18334
+ * study panes and the time axis. A maximized study pane collapses the box to
18335
+ * zero height — the mark does not appear on a study. */
18336
+ publishPricePaneBounds() {
18337
+ if (!this.mountContainer) return;
18338
+ const plotH = this.coords.height + TIME_AXIS_H;
18339
+ const price = this.scene.panes.get(PRICE_PANE_ID);
18340
+ const top = price ? price.bounds.top : 0;
18341
+ const height = price ? price.bounds.height : this.coords.height;
18342
+ const bottom = Math.max(0, plotH - (top + height));
18343
+ this.mountContainer.style.setProperty("--vela-price-pane-top", `${top}px`);
18344
+ this.mountContainer.style.setProperty("--vela-price-pane-bottom", `${bottom}px`);
18345
+ }
18297
18346
  /** The built-in mark, or the host's own when one is set. */
18298
18347
  buildAttributionEl() {
18299
18348
  return this.attributionHtml !== null ? createCustomMark(document, this.attributionHtml, this.theme.background) : createAttributionMark(document, this.theme.background);
@@ -5729,6 +5729,20 @@ function rendererDefaults() {
5729
5729
  }
5730
5730
 
5731
5731
  // src/renderers/native/layers.ts
5732
+ function foldBaseModulation(acc, next) {
5733
+ if (next == null) return acc;
5734
+ if (acc == null) return { ...next };
5735
+ return {
5736
+ candleBodyScale: minOpt(acc.candleBodyScale, next.candleBodyScale),
5737
+ candleBodyAlpha: minOpt(acc.candleBodyAlpha, next.candleBodyAlpha),
5738
+ gridAlpha: minOpt(acc.gridAlpha, next.gridAlpha)
5739
+ };
5740
+ }
5741
+ function minOpt(a, b) {
5742
+ if (a == null) return b;
5743
+ if (b == null) return a;
5744
+ return Math.min(a, b);
5745
+ }
5732
5746
  var registry2 = /* @__PURE__ */ new Map();
5733
5747
  function registerRendererLayer(def) {
5734
5748
  registry2.set(def.id, def);
@@ -6031,4 +6045,4 @@ var SidePanel = class {
6031
6045
  }
6032
6046
  };
6033
6047
 
6034
- export { AnchoredVwap, ArrowMark, Callout, CalloutBase, Comment, DEDEKIND_CURVATURE_OPTIONS, DEFAULT_DRAWING_COLOR, DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, DIRECTION_OPTIONS, DedekindTessellation, Drawing, FibRatios, FibSpiral, FixedRangeVolumeProfile, GANN_SQUARE_ARCS, GLYPH_OPTIONS, GannSquare, GlyphStamp, LINE_STYLE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, MachFigure, MeasureBox, Note, PatternDrawing, PositionTool, PriceLabel, PriceNote, RadialFib, RegressionChannel, STAMP_SIZE_OPTIONS, SegmentDrawing, SidePanel, Signpost, TEXT_SIZE_OPTIONS, TextLabel, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, formatDuration, getDrawingType, getNativeIndicator, legendActions, legendActionsProviderFor, lineSegmentIntersection, nativeIndicatorDescriptors, nativeIndicatorTypes, normalizeSettingsRow, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resetDrawingSettings, resolveEngines, settingsRowValueKeys, settingsRowVisible, sidePanels, tickerModifierIds, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments };
6048
+ export { AnchoredVwap, ArrowMark, Callout, CalloutBase, Comment, DEDEKIND_CURVATURE_OPTIONS, DEFAULT_DRAWING_COLOR, DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, DIRECTION_OPTIONS, DedekindTessellation, Drawing, FibRatios, FibSpiral, FixedRangeVolumeProfile, GANN_SQUARE_ARCS, GLYPH_OPTIONS, GannSquare, GlyphStamp, LINE_STYLE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, MachFigure, MeasureBox, Note, PatternDrawing, PositionTool, PriceLabel, PriceNote, RadialFib, RegressionChannel, STAMP_SIZE_OPTIONS, SegmentDrawing, SidePanel, Signpost, TEXT_SIZE_OPTIONS, TextLabel, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, foldBaseModulation, formatDuration, getDrawingType, getNativeIndicator, legendActions, legendActionsProviderFor, lineSegmentIntersection, nativeIndicatorDescriptors, nativeIndicatorTypes, normalizeSettingsRow, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resetDrawingSettings, resolveEngines, settingsRowValueKeys, settingsRowVisible, sidePanels, tickerModifierIds, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments };
package/dist/index.cjs CHANGED
@@ -14007,7 +14007,7 @@ var TOUCH_TAP_SLOP = 14;
14007
14007
  var DOUBLE_TAP_MS = 350;
14008
14008
  var DOUBLE_TAP_SLOP = 30;
14009
14009
  var TIME_SCALE_K = 4e-3;
14010
- var WHEEL_ZOOM_K = 25e-4;
14010
+ var WHEEL_ZOOM_K = 4e-3;
14011
14011
  function wheelZoomAnchor(coords, cursorX, rightEdge) {
14012
14012
  if (rightEdge) return { logical: coords.rightEdgeLogical, x: coords.width };
14013
14013
  return { logical: coords.xToLogical(cursorX), x: cursorX };
@@ -14061,6 +14061,8 @@ var InputController = class {
14061
14061
  // smoothed pointer velocity, px/ms
14062
14062
  this.middleDeleted = false;
14063
14063
  // the last middle press deleted a drawing (suppress autoscroll/paste)
14064
+ this.rightCancelled = false;
14065
+ // the last right press cancelled a placement (suppress the context menu)
14064
14066
  // Last cursor position over the element (NaN once it leaves) — lets a modifier
14065
14067
  // press/release re-shape the drawings preview with the pointer stationary.
14066
14068
  this.cursorX = NaN;
@@ -14085,6 +14087,14 @@ var InputController = class {
14085
14087
  this.onMiddleGuard = (e) => {
14086
14088
  if (e.button === 1 && this.middleDeleted) e.preventDefault();
14087
14089
  };
14090
+ /** A right press that cancelled a placement must not ALSO open the host's chart
14091
+ * context menu — swallow its companion event before it bubbles to the host. */
14092
+ this.onContextGuard = (e) => {
14093
+ if (!this.rightCancelled) return;
14094
+ this.rightCancelled = false;
14095
+ e.preventDefault();
14096
+ e.stopPropagation();
14097
+ };
14088
14098
  /** A modifier press/release with the pointer stationary: re-issue the last cursor
14089
14099
  * position so the placing ghost / drag preview reflects the new state immediately
14090
14100
  * (Shift's 45° angle lock, Ctrl/Cmd's momentary strong magnet). */
@@ -14101,6 +14111,11 @@ var InputController = class {
14101
14111
  if (this.middleDeleted) e.preventDefault();
14102
14112
  return;
14103
14113
  }
14114
+ if (e.button === 2) {
14115
+ this.rightCancelled = this.deps.drawingsCancelPlacement?.() ?? false;
14116
+ if (this.rightCancelled) e.preventDefault();
14117
+ return;
14118
+ }
14104
14119
  if (e.button !== 0) return;
14105
14120
  const { x, y } = this.local(e);
14106
14121
  if (e.pointerType === "touch") {
@@ -14305,6 +14320,7 @@ var InputController = class {
14305
14320
  el.addEventListener("wheel", this.onWheel, { passive: false });
14306
14321
  el.addEventListener("mousedown", this.onMiddleGuard);
14307
14322
  el.addEventListener("auxclick", this.onMiddleGuard);
14323
+ el.addEventListener("contextmenu", this.onContextGuard);
14308
14324
  const win = el.ownerDocument?.defaultView;
14309
14325
  win?.addEventListener("keydown", this.onModifier);
14310
14326
  win?.addEventListener("keyup", this.onModifier);
@@ -14326,6 +14342,7 @@ var InputController = class {
14326
14342
  el.removeEventListener("wheel", this.onWheel);
14327
14343
  el.removeEventListener("mousedown", this.onMiddleGuard);
14328
14344
  el.removeEventListener("auxclick", this.onMiddleGuard);
14345
+ el.removeEventListener("contextmenu", this.onContextGuard);
14329
14346
  this.cancelLongPress();
14330
14347
  this.touches.clear();
14331
14348
  this.el = null;
@@ -15998,8 +16015,11 @@ var ChromeRenderer = class {
15998
16015
  }
15999
16016
  ctx.font = `${scene.style.fontSize}px ${theme.fontFamily}`;
16000
16017
  ctx.textBaseline = "middle";
16001
- if (coords.barCount === 0) return;
16002
16018
  const panes = scene.orderedPanes();
16019
+ if (coords.barCount === 0) {
16020
+ this.drawPaneSeparators(ctx, scene, theme, fullW, panes);
16021
+ return;
16022
+ }
16003
16023
  const pricePane = panes.find((p) => p.kind === "price") ?? null;
16004
16024
  for (const pane of panes) {
16005
16025
  if (pane.collapsed) continue;
@@ -22157,6 +22177,16 @@ var UserDrawingController = class {
22157
22177
  if (this.eraserMode) return "pointer";
22158
22178
  return this.interaction.cursorAt(x, y);
22159
22179
  }
22180
+ /** Right-click while placing: cancel the in-progress drawing and revert to the
22181
+ * pointer — the gesture is an explicit escape, so it disarms even in
22182
+ * stay-in-drawing-mode (where Escape would leave the tool armed). Returns whether
22183
+ * the press was consumed; false lets the host's context menu open normally. */
22184
+ cancelPlacement() {
22185
+ if (!this.interaction.isPlacing()) return false;
22186
+ this.interaction.cancel();
22187
+ if (this.activeTool != null) this.emit({ kind: "arm", type: null });
22188
+ return true;
22189
+ }
22160
22190
  /** Double-click over a drawing → suppress the chart's view reset (single-click already
22161
22191
  * opens settings). Returns true only when a drawing is under the cursor. */
22162
22192
  dblClick(x, y) {
@@ -22641,6 +22671,20 @@ var VolumeRenderer = class {
22641
22671
  };
22642
22672
 
22643
22673
  // src/renderers/native/layers.ts
22674
+ function foldBaseModulation(acc, next) {
22675
+ if (next == null) return acc;
22676
+ if (acc == null) return { ...next };
22677
+ return {
22678
+ candleBodyScale: minOpt(acc.candleBodyScale, next.candleBodyScale),
22679
+ candleBodyAlpha: minOpt(acc.candleBodyAlpha, next.candleBodyAlpha),
22680
+ gridAlpha: minOpt(acc.gridAlpha, next.gridAlpha)
22681
+ };
22682
+ }
22683
+ function minOpt(a, b) {
22684
+ if (a == null) return b;
22685
+ if (b == null) return a;
22686
+ return Math.min(a, b);
22687
+ }
22644
22688
  var registry3 = /* @__PURE__ */ new Map();
22645
22689
  function registerRendererLayer(def) {
22646
22690
  registry3.set(def.id, def);
@@ -23284,7 +23328,7 @@ var NativeRenderer = class {
23284
23328
  this.scrollTargetRO = null;
23285
23329
  // eased rightOffset target while gliding back to the latest bars
23286
23330
  // Distance (px) from the plot's bottom edge to the button — tracks the bottom-most EXPANDED
23287
- // pane like the watermark: when the lower sub-panes collapse it rides up into the open pane.
23331
+ // pane: when the lower sub-panes collapse it rides up into the open pane.
23288
23332
  this.scrollBtnBottomPx = SCROLL_BTN_BOTTOM;
23289
23333
  // Distance (px) from the plot's right edge — clears the FULL scale gutter, which widens when a
23290
23334
  // pane carries merged (own-scale) columns; the constant only clears a single-column scale.
@@ -24251,6 +24295,7 @@ var NativeRenderer = class {
24251
24295
  drawingsClaim: (x, y) => this.userDrawings?.claim(x, y) ?? false,
24252
24296
  drawingsMeasureStart: (x, y) => this.userDrawings?.beginMeasureAt(x, y) ?? false,
24253
24297
  drawingsDeleteAt: (x, y) => this.userDrawings?.deleteAt(x, y) ?? false,
24298
+ drawingsCancelPlacement: () => this.userDrawings?.cancelPlacement() ?? false,
24254
24299
  drawingsSnapMode: () => this.snapMode,
24255
24300
  drawingsPointerDown: (x, y, snap, shift) => this.userDrawings?.pointerDown(x, y, snap, shift),
24256
24301
  drawingsPointerMove: (x, y, snap, shift) => this.userDrawings?.pointerMove(x, y, snap, shift),
@@ -24502,6 +24547,8 @@ var NativeRenderer = class {
24502
24547
  this.attributionEl = null;
24503
24548
  this.mountContainer?.style.removeProperty("--vela-toolbar-gutter");
24504
24549
  this.mountContainer?.style.removeProperty("--vela-scale-gutter");
24550
+ this.mountContainer?.style.removeProperty("--vela-price-pane-top");
24551
+ this.mountContainer?.style.removeProperty("--vela-price-pane-bottom");
24505
24552
  this.mountContainer = null;
24506
24553
  this.wrapper?.remove();
24507
24554
  }
@@ -25591,19 +25638,18 @@ var NativeRenderer = class {
25591
25638
  theme: this.theme
25592
25639
  });
25593
25640
  const nowMs = typeof performance !== "undefined" ? performance.now() : Date.now();
25641
+ let folded = null;
25594
25642
  for (const l of this.extLayers) {
25595
25643
  const args = this.extLayerArgs(l.def.id, pane.scale, pane.bounds, nowMs);
25596
25644
  l.instance.render(args);
25597
- if (l.def.id === this.scene.priceStyle && l.instance.modulateBase) {
25598
- const mod = l.instance.modulateBase(args);
25599
- if (mod) {
25600
- if (mod.candleBodyScale != null) this.backend.candleBodyScale = clamp012(mod.candleBodyScale) || 0.01;
25601
- if (mod.candleBodyAlpha != null) this.backend.candleBodyAlpha = clamp012(mod.candleBodyAlpha) * this.candleBodyAlpha;
25602
- if (mod.gridAlpha != null) this.backend.gridAlpha = clamp012(mod.gridAlpha);
25603
- }
25604
- }
25645
+ folded = foldBaseModulation(folded, l.instance.modulateBase?.(args) ?? null);
25605
25646
  if (this.animZoom && l.instance.animating?.()) this.animator.start();
25606
25647
  }
25648
+ if (folded) {
25649
+ if (folded.candleBodyScale != null) this.backend.candleBodyScale = clamp012(folded.candleBodyScale) || 0.01;
25650
+ if (folded.candleBodyAlpha != null) this.backend.candleBodyAlpha = clamp012(folded.candleBodyAlpha) * this.candleBodyAlpha;
25651
+ if (folded.gridAlpha != null) this.backend.gridAlpha = clamp012(folded.gridAlpha);
25652
+ }
25607
25653
  }
25608
25654
  const li = this.bars.length - 1;
25609
25655
  const liveActual = li >= 0 ? this.bars[li] : void 0;
@@ -25995,6 +26041,7 @@ var NativeRenderer = class {
25995
26041
  this.paneControls?.reposition();
25996
26042
  this.repositionScrollButton();
25997
26043
  this.positionAttribution();
26044
+ this.publishPricePaneBounds();
25998
26045
  return;
25999
26046
  }
26000
26047
  const collapsed = panes.filter((p) => p.collapsed);
@@ -26012,9 +26059,10 @@ var NativeRenderer = class {
26012
26059
  this.paneControls?.reposition();
26013
26060
  this.repositionScrollButton();
26014
26061
  this.positionAttribution();
26062
+ this.publishPricePaneBounds();
26015
26063
  }
26016
- /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area (like the
26017
- * watermark): with all lower sub-panes collapsed it settles into the lowest open pane. */
26064
+ /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area:
26065
+ * with all lower sub-panes collapsed it settles into the lowest open pane. */
26018
26066
  repositionScrollButton() {
26019
26067
  const dataHeight = this.coords.height;
26020
26068
  if (dataHeight <= 0) return;
@@ -26058,6 +26106,21 @@ var NativeRenderer = class {
26058
26106
  this.mountContainer?.style.setProperty("--vela-toolbar-gutter", `${this.toolbarGutter}px`);
26059
26107
  this.mountContainer?.style.setProperty("--vela-scale-gutter", `${this.rightAxisW}px`);
26060
26108
  }
26109
+ /** Publish the price pane's vertical insets as `--vela-price-pane-top` /
26110
+ * `--vela-price-pane-bottom` on the mount container, so the symbol watermark
26111
+ * (and any other host overlay) can clip to the price pane instead of spanning
26112
+ * study panes and the time axis. A maximized study pane collapses the box to
26113
+ * zero height — the mark does not appear on a study. */
26114
+ publishPricePaneBounds() {
26115
+ if (!this.mountContainer) return;
26116
+ const plotH = this.coords.height + TIME_AXIS_H;
26117
+ const price = this.scene.panes.get(PRICE_PANE_ID);
26118
+ const top = price ? price.bounds.top : 0;
26119
+ const height = price ? price.bounds.height : this.coords.height;
26120
+ const bottom = Math.max(0, plotH - (top + height));
26121
+ this.mountContainer.style.setProperty("--vela-price-pane-top", `${top}px`);
26122
+ this.mountContainer.style.setProperty("--vela-price-pane-bottom", `${bottom}px`);
26123
+ }
26061
26124
  /** The built-in mark, or the host's own when one is set. */
26062
26125
  buildAttributionEl() {
26063
26126
  return this.attributionHtml !== null ? createCustomMark(document, this.attributionHtml, this.theme.background) : createAttributionMark(document, this.theme.background);
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@ export { B as BarsChangeReason, C as ContextSelect, b as DataControl, c as Drawi
3
3
  import { D as Drawing, S as SerializedDrawing, U as Unsubscribe, L as LineStyle, P as PriceStyle, I as IChartRenderer, R as RendererCapabilities, d as RendererDisplayOptions, e as IndicatorRenderHandle, f as IndicatorStatus, c as VelaTheme, O as OHLCV, g as Pane, h as PaneAction, i as MoveTarget, j as IndicatorModel, k as ScenePatch, l as InputValue, m as SymbolPickerFn, n as LegendActionView, o as InputChangeEvent, T as ThemeName, C as CrosshairEvent, p as ClickEvent, A as AxisLongPressEvent, a as VisibleRange, q as DataWindowReadout, r as IDrawingsRendererPort, s as Millis, t as SnapMode, u as DrawingTypeKey, v as ToolbarDefinition, M as MarketConfig } from './options-XTBpbx0s.cjs';
4
4
  export { w as AddIndicatorOptions, B as Background, x as BoxFontFamily, y as BoxHAlign, z as BoxTextSize, E as BoxVAlign, F as CandleBarColor, G as CandleSeries, H as CandleStyle, J as DataWindowGroup, K as DataWindowOHLC, Q as DataWindowRow, W as DirtyRange, X as DrawingBox, Y as DrawingExtend, Z as DrawingIntent, _ as DrawingLabel, $ as DrawingLine, a0 as DrawingLinefill, a1 as DrawingMode, a2 as DrawingPoint, a3 as DrawingPolyline, a4 as DrawingStyle, a5 as DrawingTable, a6 as DrawingText, a7 as DrawingXLoc, a8 as DrawingsOption, a9 as Fill, aa as FillGradientStop, ab as IndicatorMeta, ac as InputSchema, ad as InputType, ae as LabelStyle, af as LabelYLoc, ag as LineLikeKind, ah as LineLikeSeries, ai as LineLikeStyle, aj as MarkerPoint, ak as MarkerSeries, al as MarketSnapshot, am as MarketSwitch, an as PaneHint, ao as PaneKind, ap as PolylinePoint, aq as PriceLine, ar as Projector, as as ProviderName, at as RendererConstructor, au as Scene, av as SchemaPatch, aw as SeriesKind, ax as SeriesPoint, ay as SeriesSpec, az as SeriesValueDelta, aA as SettingsField, aB as SettingsSchema, aC as TableCell, aD as TableMerge, aE as TablePosition, aF as ToolbarGroupConfig, aG as TradeExecution, aH as ValuePatch, b as VelaOptions, V as VisibleRangePreset, aI as buildToolbar, aJ as defaultToolbar } from './options-XTBpbx0s.cjs';
5
5
  import { M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, S as SymbolInfo, b as ProviderCapabilities, B as BarRange } from './DataProvider-gnzv-dgc.cjs';
6
- export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CROSSHAIR, f as ChartTypeDefinition, g as ChartTypeSettingsInstance, h as ChartTypeSettingsSection, i as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, j as INVALID, k as IdentifiableKind, M as MARKER, N as NEUTRAL, l as NormalizedSettingsRow, R as RendererLayerArgs, m as RendererLayerDefinition, n as RendererLayerInstance, S as SERIES_LINE, o as SESSION_OFF, p as SESSION_POST, q as SESSION_PRE, r as SLATE, s as SLATE_DEEP, t as SeriesDataEngine, u as SeriesDataEngineHost, v as SettingsInlineControl, w as SettingsRowCondition, x as SettingsRowDescriptor, y as SettingsRowInlineNumber, z as SettingsRowSwatch, E as SettingsRowValueKey, F as SettingsRowWhen, G as SettingsRowWidth, J as SettingsSelectOption, K as SettingsValueRow, T as TRADE_EXIT, L as TRADE_LONG, O as TRADE_SHORT, V as VALID, W as WARNING, P as categoricalColor, Q as chartType, U as chartTypes, X as createDrawing, Y as deserializeDrawing, Z as drawingTypes, _ as getDrawingType, $ as normalizeSettingsRow, a0 as registerChartType, a1 as registerDrawingType, a2 as registerRendererDefaults, a3 as registerRendererLayer, a4 as rendererDefaults, a5 as rendererLayers, a6 as settingsRowValueKeys, a7 as stableSeriesId, a8 as tickerModifierIds, a9 as unregisterChartType, aa as unregisterRendererDefaults, ab as unregisterRendererLayer } from './plugin-DfH4Y-Om.cjs';
6
+ export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CROSSHAIR, f as ChartTypeDefinition, g as ChartTypeSettingsInstance, h as ChartTypeSettingsSection, i as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, j as INVALID, k as IdentifiableKind, M as MARKER, N as NEUTRAL, l as NormalizedSettingsRow, R as RendererLayerArgs, m as RendererLayerDefinition, n as RendererLayerInstance, S as SERIES_LINE, o as SESSION_OFF, p as SESSION_POST, q as SESSION_PRE, r as SLATE, s as SLATE_DEEP, t as SeriesDataEngine, u as SeriesDataEngineHost, v as SettingsInlineControl, w as SettingsRowCondition, x as SettingsRowDescriptor, y as SettingsRowInlineNumber, z as SettingsRowSwatch, E as SettingsRowValueKey, F as SettingsRowWhen, G as SettingsRowWidth, J as SettingsSelectOption, K as SettingsValueRow, T as TRADE_EXIT, L as TRADE_LONG, O as TRADE_SHORT, V as VALID, W as WARNING, P as categoricalColor, Q as chartType, U as chartTypes, X as createDrawing, Y as deserializeDrawing, Z as drawingTypes, _ as getDrawingType, $ as normalizeSettingsRow, a0 as registerChartType, a1 as registerDrawingType, a2 as registerRendererDefaults, a3 as registerRendererLayer, a4 as rendererDefaults, a5 as rendererLayers, a6 as settingsRowValueKeys, a7 as stableSeriesId, a8 as tickerModifierIds, a9 as unregisterChartType, aa as unregisterRendererDefaults, ab as unregisterRendererLayer } from './plugin-DlidwMj6.cjs';
7
7
  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-CT9ZwIGz.cjs';
8
8
  export { i as iconMarkup, r as registerIcon } from './icons-BZYbJXSV.cjs';
9
9
  export { a as KeyBindingDescriptor, R as ResolvedBinding } from './keymap-CGOz5F5f.cjs';
@@ -871,8 +871,8 @@ declare class NativeRenderer implements IChartRenderer {
871
871
  private syncTables;
872
872
  private repositionTables;
873
873
  private layoutPanes;
874
- /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area (like the
875
- * watermark): with all lower sub-panes collapsed it settles into the lowest open pane. */
874
+ /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area:
875
+ * with all lower sub-panes collapsed it settles into the lowest open pane. */
876
876
  private repositionScrollButton;
877
877
  /** For each collapsed pane, the master (master-scale) indicator id whose legend row stays in the
878
878
  * strip — merged own-scale indicators are hidden while collapsed. */
@@ -885,6 +885,12 @@ declare class NativeRenderer implements IChartRenderer {
885
885
  * status line, a watermark, a custom legend) can anchor to the plot's edges
886
886
  * without reaching into the renderer's DOM. */
887
887
  private publishGutters;
888
+ /** Publish the price pane's vertical insets as `--vela-price-pane-top` /
889
+ * `--vela-price-pane-bottom` on the mount container, so the symbol watermark
890
+ * (and any other host overlay) can clip to the price pane instead of spanning
891
+ * study panes and the time axis. A maximized study pane collapses the box to
892
+ * zero height — the mark does not appear on a study. */
893
+ private publishPricePaneBounds;
888
894
  /** The built-in mark, or the host's own when one is set. */
889
895
  private buildAttributionEl;
890
896
  /** Swap the mark in place — the content kind changed (built-in ↔ host-supplied). */
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { B as BarsChangeReason, C as ContextSelect, b as DataControl, c as Drawi
3
3
  import { D as Drawing, S as SerializedDrawing, U as Unsubscribe, L as LineStyle, P as PriceStyle, I as IChartRenderer, R as RendererCapabilities, d as RendererDisplayOptions, e as IndicatorRenderHandle, f as IndicatorStatus, c as VelaTheme, O as OHLCV, g as Pane, h as PaneAction, i as MoveTarget, j as IndicatorModel, k as ScenePatch, l as InputValue, m as SymbolPickerFn, n as LegendActionView, o as InputChangeEvent, T as ThemeName, C as CrosshairEvent, p as ClickEvent, A as AxisLongPressEvent, a as VisibleRange, q as DataWindowReadout, r as IDrawingsRendererPort, s as Millis, t as SnapMode, u as DrawingTypeKey, v as ToolbarDefinition, M as MarketConfig } from './options-XTBpbx0s.js';
4
4
  export { w as AddIndicatorOptions, B as Background, x as BoxFontFamily, y as BoxHAlign, z as BoxTextSize, E as BoxVAlign, F as CandleBarColor, G as CandleSeries, H as CandleStyle, J as DataWindowGroup, K as DataWindowOHLC, Q as DataWindowRow, W as DirtyRange, X as DrawingBox, Y as DrawingExtend, Z as DrawingIntent, _ as DrawingLabel, $ as DrawingLine, a0 as DrawingLinefill, a1 as DrawingMode, a2 as DrawingPoint, a3 as DrawingPolyline, a4 as DrawingStyle, a5 as DrawingTable, a6 as DrawingText, a7 as DrawingXLoc, a8 as DrawingsOption, a9 as Fill, aa as FillGradientStop, ab as IndicatorMeta, ac as InputSchema, ad as InputType, ae as LabelStyle, af as LabelYLoc, ag as LineLikeKind, ah as LineLikeSeries, ai as LineLikeStyle, aj as MarkerPoint, ak as MarkerSeries, al as MarketSnapshot, am as MarketSwitch, an as PaneHint, ao as PaneKind, ap as PolylinePoint, aq as PriceLine, ar as Projector, as as ProviderName, at as RendererConstructor, au as Scene, av as SchemaPatch, aw as SeriesKind, ax as SeriesPoint, ay as SeriesSpec, az as SeriesValueDelta, aA as SettingsField, aB as SettingsSchema, aC as TableCell, aD as TableMerge, aE as TablePosition, aF as ToolbarGroupConfig, aG as TradeExecution, aH as ValuePatch, b as VelaOptions, V as VisibleRangePreset, aI as buildToolbar, aJ as defaultToolbar } from './options-XTBpbx0s.js';
5
5
  import { M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, S as SymbolInfo, b as ProviderCapabilities, B as BarRange } from './DataProvider-DTOEXKTI.js';
6
- export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CROSSHAIR, f as ChartTypeDefinition, g as ChartTypeSettingsInstance, h as ChartTypeSettingsSection, i as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, j as INVALID, k as IdentifiableKind, M as MARKER, N as NEUTRAL, l as NormalizedSettingsRow, R as RendererLayerArgs, m as RendererLayerDefinition, n as RendererLayerInstance, S as SERIES_LINE, o as SESSION_OFF, p as SESSION_POST, q as SESSION_PRE, r as SLATE, s as SLATE_DEEP, t as SeriesDataEngine, u as SeriesDataEngineHost, v as SettingsInlineControl, w as SettingsRowCondition, x as SettingsRowDescriptor, y as SettingsRowInlineNumber, z as SettingsRowSwatch, E as SettingsRowValueKey, F as SettingsRowWhen, G as SettingsRowWidth, J as SettingsSelectOption, K as SettingsValueRow, T as TRADE_EXIT, L as TRADE_LONG, O as TRADE_SHORT, V as VALID, W as WARNING, P as categoricalColor, Q as chartType, U as chartTypes, X as createDrawing, Y as deserializeDrawing, Z as drawingTypes, _ as getDrawingType, $ as normalizeSettingsRow, a0 as registerChartType, a1 as registerDrawingType, a2 as registerRendererDefaults, a3 as registerRendererLayer, a4 as rendererDefaults, a5 as rendererLayers, a6 as settingsRowValueKeys, a7 as stableSeriesId, a8 as tickerModifierIds, a9 as unregisterChartType, aa as unregisterRendererDefaults, ab as unregisterRendererLayer } from './plugin-CnNd7cuF.js';
6
+ export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CROSSHAIR, f as ChartTypeDefinition, g as ChartTypeSettingsInstance, h as ChartTypeSettingsSection, i as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, j as INVALID, k as IdentifiableKind, M as MARKER, N as NEUTRAL, l as NormalizedSettingsRow, R as RendererLayerArgs, m as RendererLayerDefinition, n as RendererLayerInstance, S as SERIES_LINE, o as SESSION_OFF, p as SESSION_POST, q as SESSION_PRE, r as SLATE, s as SLATE_DEEP, t as SeriesDataEngine, u as SeriesDataEngineHost, v as SettingsInlineControl, w as SettingsRowCondition, x as SettingsRowDescriptor, y as SettingsRowInlineNumber, z as SettingsRowSwatch, E as SettingsRowValueKey, F as SettingsRowWhen, G as SettingsRowWidth, J as SettingsSelectOption, K as SettingsValueRow, T as TRADE_EXIT, L as TRADE_LONG, O as TRADE_SHORT, V as VALID, W as WARNING, P as categoricalColor, Q as chartType, U as chartTypes, X as createDrawing, Y as deserializeDrawing, Z as drawingTypes, _ as getDrawingType, $ as normalizeSettingsRow, a0 as registerChartType, a1 as registerDrawingType, a2 as registerRendererDefaults, a3 as registerRendererLayer, a4 as rendererDefaults, a5 as rendererLayers, a6 as settingsRowValueKeys, a7 as stableSeriesId, a8 as tickerModifierIds, a9 as unregisterChartType, aa as unregisterRendererDefaults, ab as unregisterRendererLayer } from './plugin-DP6A4t4o.js';
7
7
  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-CT9ZwIGz.js';
8
8
  export { i as iconMarkup, r as registerIcon } from './icons-BZYbJXSV.js';
9
9
  export { a as KeyBindingDescriptor, R as ResolvedBinding } from './keymap-CGOz5F5f.js';
@@ -871,8 +871,8 @@ declare class NativeRenderer implements IChartRenderer {
871
871
  private syncTables;
872
872
  private repositionTables;
873
873
  private layoutPanes;
874
- /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area (like the
875
- * watermark): with all lower sub-panes collapsed it settles into the lowest open pane. */
874
+ /** Pin the scroll-to-realtime button above the bottom-most EXPANDED pane's data area:
875
+ * with all lower sub-panes collapsed it settles into the lowest open pane. */
876
876
  private repositionScrollButton;
877
877
  /** For each collapsed pane, the master (master-scale) indicator id whose legend row stays in the
878
878
  * strip — merged own-scale indicators are hidden while collapsed. */
@@ -885,6 +885,12 @@ declare class NativeRenderer implements IChartRenderer {
885
885
  * status line, a watermark, a custom legend) can anchor to the plot's edges
886
886
  * without reaching into the renderer's DOM. */
887
887
  private publishGutters;
888
+ /** Publish the price pane's vertical insets as `--vela-price-pane-top` /
889
+ * `--vela-price-pane-bottom` on the mount container, so the symbol watermark
890
+ * (and any other host overlay) can clip to the price pane instead of spanning
891
+ * study panes and the time axis. A maximized study pane collapses the box to
892
+ * zero height — the mark does not appear on a study. */
893
+ private publishPricePaneBounds;
888
894
  /** The built-in mark, or the host's own when one is set. */
889
895
  private buildAttributionEl;
890
896
  /** Swap the mark in place — the content kind changed (built-in ↔ host-supplied). */
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { stableSeriesId } from './chunk-Q3XQHLIH.js';
2
- export { BarStore, CachingDataFeed, DARK_THEME, DataControl, DrawingStore, DrawingToolbar, DrawingsControl, LIGHT_THEME, MultiProviderFeed, NativeRenderer, RendererControl, TypedEventBus, Vela, buildToolbar, defaultToolbar, resolveTheme, sharedBarStore, timeframeToMs } from './chunk-RRFGWZNJ.js';
3
- export { DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_WIDTH, Drawing, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, getDrawingType, getNativeIndicator, legendActions, nativeIndicatorDescriptors, nativeIndicatorTypes, normalizeSettingsRow, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resolveEngines, settingsRowValueKeys, sidePanels, tickerModifierIds, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments } from './chunk-B5TIKQJ5.js';
2
+ export { BarStore, CachingDataFeed, DARK_THEME, DataControl, DrawingStore, DrawingToolbar, DrawingsControl, LIGHT_THEME, MultiProviderFeed, NativeRenderer, RendererControl, TypedEventBus, Vela, buildToolbar, defaultToolbar, resolveTheme, sharedBarStore, timeframeToMs } from './chunk-L5NTMWPP.js';
3
+ export { DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_WIDTH, Drawing, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, getDrawingType, getNativeIndicator, legendActions, nativeIndicatorDescriptors, nativeIndicatorTypes, normalizeSettingsRow, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resolveEngines, settingsRowValueKeys, sidePanels, tickerModifierIds, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments } from './chunk-WJKLBYRM.js';
4
4
  import './chunk-ATPU5CI6.js';
5
5
  export { ACCENT, ACCENT_BRIGHT, BEARISH, BULLISH, CATEGORICAL, CROSSHAIR, HIGHLIGHT, INFO, INVALID, MARKER, NEUTRAL, SERIES_LINE, SESSION_OFF, SESSION_POST, SESSION_PRE, SLATE, SLATE_DEEP, TRADE_EXIT, TRADE_LONG, TRADE_SHORT, VALID, WARNING, categoricalColor, iconMarkup, registerIcon } from './chunk-LJLZR44Y.js';
@@ -600,7 +600,7 @@ interface RendererLayerArgs {
600
600
  y: number;
601
601
  } | null;
602
602
  }
603
- /** How the active style's layer dims/slims the BASE painting under it (see
603
+ /** How a layer dims/slims the BASE painting under it (see
604
604
  * {@link RendererLayerInstance.modulateBase}). Omitted fields keep their defaults. */
605
605
  interface BasePaintingModulation {
606
606
  /** Candle body width multiplier, (0..1] (1 = full width). */
@@ -621,9 +621,10 @@ interface RendererLayerInstance {
621
621
  /**
622
622
  * How the base painting (candles, grid) should be dimmed/slimmed under this layer for
623
623
  * the CURRENT frame — a gradual counterpart of the chart type's all-or-nothing
624
- * `basePainting: 'none'`. Called after `render`, only for the layer whose id matches
625
- * the active price style; returning null (or omitting the method) leaves the base
626
- * painting untouched. Values are clamped by the renderer.
624
+ * `basePainting: 'none'`. Called after `render` on every mounted layer that implements
625
+ * it (chart-type and overlay alike); returning null (or omitting the method) is no
626
+ * opinion. When several layers speak, each field keeps the strongest (smallest)
627
+ * request. Values are clamped by the renderer.
627
628
  */
628
629
  modulateBase?(args: RendererLayerArgs): BasePaintingModulation | null;
629
630
  /** The renderer unmounted — release everything (the canvas itself is removed by the renderer). */
@@ -600,7 +600,7 @@ interface RendererLayerArgs {
600
600
  y: number;
601
601
  } | null;
602
602
  }
603
- /** How the active style's layer dims/slims the BASE painting under it (see
603
+ /** How a layer dims/slims the BASE painting under it (see
604
604
  * {@link RendererLayerInstance.modulateBase}). Omitted fields keep their defaults. */
605
605
  interface BasePaintingModulation {
606
606
  /** Candle body width multiplier, (0..1] (1 = full width). */
@@ -621,9 +621,10 @@ interface RendererLayerInstance {
621
621
  /**
622
622
  * How the base painting (candles, grid) should be dimmed/slimmed under this layer for
623
623
  * the CURRENT frame — a gradual counterpart of the chart type's all-or-nothing
624
- * `basePainting: 'none'`. Called after `render`, only for the layer whose id matches
625
- * the active price style; returning null (or omitting the method) leaves the base
626
- * painting untouched. Values are clamped by the renderer.
624
+ * `basePainting: 'none'`. Called after `render` on every mounted layer that implements
625
+ * it (chart-type and overlay alike); returning null (or omitting the method) is no
626
+ * opinion. When several layers speak, each field keeps the strongest (smallest)
627
+ * request. Values are clamped by the renderer.
627
628
  */
628
629
  modulateBase?(args: RendererLayerArgs): BasePaintingModulation | null;
629
630
  /** The renderer unmounted — release everything (the canvas itself is removed by the renderer). */
package/dist/plugin.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CROSSHAIR, f as ChartTypeDefinition, g as ChartTypeSettingsInstance, h as ChartTypeSettingsSection, i as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, j as INVALID, k as IdentifiableKind, M as MARKER, N as NEUTRAL, l as NormalizedSettingsRow, R as RendererLayerArgs, m as RendererLayerDefinition, n as RendererLayerInstance, S as SERIES_LINE, o as SESSION_OFF, p as SESSION_POST, q as SESSION_PRE, r as SLATE, s as SLATE_DEEP, t as SeriesDataEngine, u as SeriesDataEngineHost, v as SettingsInlineControl, w as SettingsRowCondition, x as SettingsRowDescriptor, y as SettingsRowInlineNumber, z as SettingsRowSwatch, E as SettingsRowValueKey, F as SettingsRowWhen, G as SettingsRowWidth, J as SettingsSelectOption, K as SettingsValueRow, T as TRADE_EXIT, L as TRADE_LONG, O as TRADE_SHORT, V as VALID, W as WARNING, P as categoricalColor, Q as chartType, U as chartTypes, Z as drawingTypes, _ as getDrawingType, $ as normalizeSettingsRow, a0 as registerChartType, a2 as registerRendererDefaults, a3 as registerRendererLayer, a4 as rendererDefaults, a5 as rendererLayers, a6 as settingsRowValueKeys, a7 as stableSeriesId, a8 as tickerModifierIds, a9 as unregisterChartType, aa as unregisterRendererDefaults, ab as unregisterRendererLayer } from './plugin-DfH4Y-Om.cjs';
1
+ export { A as ACCENT, a as ACCENT_BRIGHT, B as BEARISH, b as BULLISH, c as BarTransform, d as BasePaintingModulation, C as CATEGORICAL, e as CROSSHAIR, f as ChartTypeDefinition, g as ChartTypeSettingsInstance, h as ChartTypeSettingsSection, i as ChartTypeSettingsSubsection, D as DrawingTypeMeta, H as HIGHLIGHT, I as INFO, j as INVALID, k as IdentifiableKind, M as MARKER, N as NEUTRAL, l as NormalizedSettingsRow, R as RendererLayerArgs, m as RendererLayerDefinition, n as RendererLayerInstance, S as SERIES_LINE, o as SESSION_OFF, p as SESSION_POST, q as SESSION_PRE, r as SLATE, s as SLATE_DEEP, t as SeriesDataEngine, u as SeriesDataEngineHost, v as SettingsInlineControl, w as SettingsRowCondition, x as SettingsRowDescriptor, y as SettingsRowInlineNumber, z as SettingsRowSwatch, E as SettingsRowValueKey, F as SettingsRowWhen, G as SettingsRowWidth, J as SettingsSelectOption, K as SettingsValueRow, T as TRADE_EXIT, L as TRADE_LONG, O as TRADE_SHORT, V as VALID, W as WARNING, P as categoricalColor, Q as chartType, U as chartTypes, Z as drawingTypes, _ as getDrawingType, $ as normalizeSettingsRow, a0 as registerChartType, a2 as registerRendererDefaults, a3 as registerRendererLayer, a4 as rendererDefaults, a5 as rendererLayers, a6 as settingsRowValueKeys, a7 as stableSeriesId, a8 as tickerModifierIds, a9 as unregisterChartType, aa as unregisterRendererDefaults, ab as unregisterRendererLayer } from './plugin-DlidwMj6.cjs';
2
2
  export { B as BarsChangeReason, C as ContextSelect, E as EngineAlert, d as EngineCapabilities, e as EngineContextSnapshot, f as EngineFactory, g as EngineWarning, h as ExecutionHandlers, i as ExecutionMarket, j as ExecutionRequest, k as ExecutionSession, F as FetchSeries, L as LegendActionDescriptor, n as LegendIndicatorInfo, N as NativeIndicator, o as NativeIndicatorContext, p as NativeIndicatorDescriptor, q as NativeIndicatorInfo, r as NativeIndicatorOutput, s as PreparedScript, a as ScriptRun, w as ScriptRunCause, x as ScriptRunResult, S as ScriptingEngine, y as SidePanelButton, z as SidePanelDescriptor, A as SidePanelHandle, G as SidePanelHeader, H as StrategyFill, J as StrategyState, K as StrategyTrade, Q as VisibleBarRange, U as WidgetActionDescriptor, X as WidgetActionTarget, Y as WidgetAttachment, W as WidgetContext, Z as getNativeIndicator, _ as legendActions, a0 as nativeIndicatorTypes, a1 as registerDefaultEngine, a2 as registerLegendAction, a3 as registerNativeIndicator, a4 as registerSidePanel, a5 as registerWidgetAction, a6 as registerWidgetAttachment, a7 as resolveEngines, a8 as sidePanels, a9 as unregisterDefaultEngine, aa as unregisterLegendAction, ab as unregisterNativeIndicator, ac as unregisterSidePanel, ad as unregisterWidgetAction, ae as unregisterWidgetAttachment, af as widgetActions, ag as widgetAttachments } from './contributions-Ci_i3IN2.cjs';
3
3
  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-CT9ZwIGz.cjs';
4
4
  export { B as Background, x as BoxFontFamily, y as BoxHAlign, z as BoxTextSize, E as BoxVAlign, F as CandleBarColor, G as CandleSeries, H as CandleStyle, W as DirtyRange, X as DrawingBox, Y as DrawingExtend, _ as DrawingLabel, $ as DrawingLine, a0 as DrawingLinefill, a3 as DrawingPolyline, a5 as DrawingTable, u as DrawingTypeKey, a7 as DrawingXLoc, a9 as Fill, aa as FillGradientStop, ab as IndicatorMeta, j as IndicatorModel, ac as InputSchema, ad as InputType, l as InputValue, ae as LabelStyle, af as LabelYLoc, ag as LineLikeKind, ah as LineLikeSeries, ai as LineLikeStyle, L as LineStyle, aj as MarkerPoint, ak as MarkerSeries, s as Millis, O as OHLCV, g as Pane, an as PaneHint, ao as PaneKind, ap as PolylinePoint, aq as PriceLine, P as PriceStyle, au as Scene, k as ScenePatch, av as SchemaPatch, aw as SeriesKind, ax as SeriesPoint, ay as SeriesSpec, az as SeriesValueDelta, aC as TableCell, aD as TableMerge, aE as TablePosition, aG as TradeExecution, aH as ValuePatch } from './options-XTBpbx0s.cjs';