@trdrs/quickcharts 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3082,7 +3082,8 @@ var FEATURE_KEYS = {
3082
3082
  replay: "flag",
3083
3083
  history: "flag",
3084
3084
  sessions: "flag",
3085
- crosshair: "flag"
3085
+ crosshair: "flag",
3086
+ navigation: "flag"
3086
3087
  };
3087
3088
  var TOP_BAR_KEYS = {
3088
3089
  symbol: "flag",
@@ -3111,7 +3112,9 @@ var UI_KEYS = {
3111
3112
  toasts: "flag",
3112
3113
  symbolSearch: "flag",
3113
3114
  indicatorPicker: "flag",
3114
- indicatorSettings: "flag"
3115
+ indicatorSettings: "flag",
3116
+ priceScale: "flag",
3117
+ crosshair: { horizontal: "flag", labels: "flag", solid: "flag" }
3115
3118
  };
3116
3119
  function checkKeys(path, value, keys) {
3117
3120
  if (value === void 0) return;
@@ -3139,7 +3142,8 @@ function resolveFeatures(config) {
3139
3142
  replay: on(config?.replay),
3140
3143
  history: on(config?.history),
3141
3144
  sessions: on(config?.sessions),
3142
- crosshair: on(config?.crosshair)
3145
+ crosshair: on(config?.crosshair),
3146
+ navigation: on(config?.navigation)
3143
3147
  };
3144
3148
  }
3145
3149
  var shown = (value) => value !== false;
@@ -3155,6 +3159,9 @@ function resolveUi(config, features, offered = {}) {
3155
3159
  const inLegend = (key) => legend2 && (typeof legendConfig !== "object" || shown(legendConfig[key]));
3156
3160
  const symbolSearch = shown(config?.symbolSearch);
3157
3161
  const indicatorPicker = shown(config?.indicatorPicker);
3162
+ const crosshairConfig = config?.crosshair;
3163
+ const crosshair = features.crosshair && shown(crosshairConfig);
3164
+ const inCrosshair = (key) => crosshair && (typeof crosshairConfig !== "object" || shown(crosshairConfig[key]));
3158
3165
  return {
3159
3166
  topBar,
3160
3167
  symbolPill: inBar("symbol") && symbolSearch,
@@ -3178,13 +3185,19 @@ function resolveUi(config, features, offered = {}) {
3178
3185
  legend: legend2,
3179
3186
  legendValues: inLegend("values"),
3180
3187
  marketStatus: inLegend("marketStatus"),
3181
- navigation: shown(config?.navigation),
3188
+ navigation: features.navigation && shown(config?.navigation),
3182
3189
  contextMenu: shown(config?.contextMenu),
3183
3190
  replayTransport: features.replay && shown(config?.replayTransport),
3184
3191
  toasts: shown(config?.toasts),
3185
3192
  symbolSearch,
3186
3193
  indicatorPicker,
3187
- indicatorSettings: shown(config?.indicatorSettings)
3194
+ indicatorSettings: shown(config?.indicatorSettings),
3195
+ priceScale: shown(config?.priceScale),
3196
+ crosshair,
3197
+ crosshairHorizontal: inCrosshair("horizontal"),
3198
+ crosshairLabels: inCrosshair("labels"),
3199
+ // Solid is the one part that is off unless named: a crosshair is dashed by default.
3200
+ crosshairSolid: crosshair && typeof crosshairConfig === "object" && crosshairConfig.solid === true
3188
3201
  };
3189
3202
  }
3190
3203
  function canCopyImage() {
@@ -3313,6 +3326,29 @@ function styleOptions(style, paint) {
3313
3326
  return candleOptions(paint);
3314
3327
  }
3315
3328
  }
3329
+ function fadedStyleOptions(style, paint, alpha) {
3330
+ const a = Math.min(1, Math.max(0, alpha));
3331
+ const up = paint.appearance.upColor;
3332
+ const down = paint.appearance.downColor;
3333
+ switch (style) {
3334
+ case "line":
3335
+ case "stepline":
3336
+ return { color: withAlpha2(paint.canvas.neutral, a) };
3337
+ case "area":
3338
+ return { lineColor: withAlpha2(up, a), topColor: withAlpha2(up, 0.28 * a), bottomColor: withAlpha2(up, 0.04 * a) };
3339
+ case "baseline":
3340
+ return {
3341
+ topLineColor: withAlpha2(up, a),
3342
+ bottomLineColor: withAlpha2(down, a),
3343
+ topFillColor1: withAlpha2(up, 0.28 * a),
3344
+ topFillColor2: withAlpha2(up, 0.04 * a),
3345
+ bottomFillColor1: withAlpha2(down, 0.04 * a),
3346
+ bottomFillColor2: withAlpha2(down, 0.28 * a)
3347
+ };
3348
+ default:
3349
+ return styleOptions(style, paint);
3350
+ }
3351
+ }
3316
3352
  function lineOptions(paint) {
3317
3353
  return { color: paint.canvas.neutral, lineWidth: 2 };
3318
3354
  }
@@ -4963,6 +4999,7 @@ import {
4963
4999
  createChart as createRenderer,
4964
5000
  HistogramSeries as HistogramSeries2,
4965
5001
  LineSeries as LineSeries4,
5002
+ LineStyle as LineStyle3,
4966
5003
  TrackingModeExitMode
4967
5004
  } from "lightweight-charts";
4968
5005
 
@@ -5017,6 +5054,59 @@ function coerceScaleMode(raw) {
5017
5054
  return SCALE_MODES.includes(raw ?? "") ? raw : "normal";
5018
5055
  }
5019
5056
 
5057
+ // src/widget/styleMorph.ts
5058
+ var STYLE_MORPH_MS = 500;
5059
+ function morphEase(t) {
5060
+ const clamped = Math.min(1, Math.max(0, t));
5061
+ return (1 - Math.cos(Math.PI * clamped)) / 2;
5062
+ }
5063
+ function foldBar(bar, fold) {
5064
+ const keep = 1 - Math.min(1, Math.max(0, fold));
5065
+ return {
5066
+ time: bar.t,
5067
+ open: bar.c + (bar.o - bar.c) * keep,
5068
+ high: bar.c + (bar.h - bar.c) * keep,
5069
+ low: bar.c + (bar.l - bar.c) * keep,
5070
+ close: bar.c
5071
+ };
5072
+ }
5073
+ function startStyleMorph(deps) {
5074
+ const frame = deps.frame ?? ((tick2) => requestAnimationFrame(tick2));
5075
+ const cancel = deps.cancelFrame ?? ((handle2) => cancelAnimationFrame(handle2));
5076
+ const now = deps.now ?? (() => performance.now());
5077
+ const start = now();
5078
+ let handle = null;
5079
+ let ended = false;
5080
+ const draw = (t) => {
5081
+ const p = morphEase(t);
5082
+ const fold = deps.direction === "fold" ? p : 1 - p;
5083
+ deps.bars.setData(deps.shown().map((bar) => foldBar(bar, fold)));
5084
+ deps.fadeLine(fold);
5085
+ };
5086
+ const finish = () => {
5087
+ if (ended) return;
5088
+ ended = true;
5089
+ if (handle !== null) cancel(handle);
5090
+ handle = null;
5091
+ draw(1);
5092
+ deps.done();
5093
+ };
5094
+ const tick = () => {
5095
+ handle = null;
5096
+ if (ended) return;
5097
+ const t = (now() - start) / STYLE_MORPH_MS;
5098
+ if (t >= 1) {
5099
+ finish();
5100
+ return;
5101
+ }
5102
+ draw(t);
5103
+ handle = frame(tick);
5104
+ };
5105
+ draw(0);
5106
+ handle = frame(tick);
5107
+ return { running: () => !ended, finish };
5108
+ }
5109
+
5020
5110
  // src/widget/baselineLevel.ts
5021
5111
  var BASELINE_SCREEN_PERCENT = 50;
5022
5112
  var BASELINE_DRIFT_PX = 0.5;
@@ -5710,8 +5800,8 @@ function bundledGlyphSource(glyph2) {
5710
5800
  }
5711
5801
 
5712
5802
  // src/pointerInput.ts
5713
- function pointerLock(locked) {
5714
- const on = !locked;
5803
+ function pointerLock(locked, navigable = true) {
5804
+ const on = !locked && navigable;
5715
5805
  return {
5716
5806
  handleScroll: on,
5717
5807
  handleScale: { mouseWheel: on, pinch: false, axisPressedMouseMove: on, axisDoubleClickReset: on },
@@ -6825,7 +6915,7 @@ function attachDrawings(options) {
6825
6915
  const locked = () => allLocked || workflow().allLocked === true;
6826
6916
  const changed = () => events.onChange?.();
6827
6917
  const lockPointer = (locked2) => {
6828
- const lock = pointerLock(locked2);
6918
+ const lock = pointerLock(locked2, options.navigable ?? true);
6829
6919
  chart.applyOptions({ handleScroll: lock.handleScroll, handleScale: lock.handleScale });
6830
6920
  container.style.touchAction = lock.touchAction;
6831
6921
  };
@@ -10339,6 +10429,7 @@ function attachDrawingsPlane(deps) {
10339
10429
  const handle = attachDrawings({
10340
10430
  chart: deps.chart,
10341
10431
  series: deps.series,
10432
+ navigable: deps.navigable,
10342
10433
  container: deps.container,
10343
10434
  symbol: deps.symbol,
10344
10435
  timeframe: deps.timeframe,
@@ -12754,6 +12845,7 @@ function composeFormingBar(parent, subs, k) {
12754
12845
  }
12755
12846
 
12756
12847
  // src/widget/replay.ts
12848
+ var START_HOLD_MS = 250;
12757
12849
  function coerceReplaySpeed(raw) {
12758
12850
  const n = Number(raw);
12759
12851
  return REPLAY_SPEEDS.includes(n) ? n : 10;
@@ -12772,6 +12864,13 @@ function attachReplayPlane(deps) {
12772
12864
  let stepping = null;
12773
12865
  let generation = 0;
12774
12866
  let destroyed = false;
12867
+ let glide = null;
12868
+ const stopGlide = () => {
12869
+ if (glide) {
12870
+ clearTimeout(glide);
12871
+ glide = null;
12872
+ }
12873
+ };
12775
12874
  const invalidateStep = () => {
12776
12875
  generation += 1;
12777
12876
  stepping = null;
@@ -12792,15 +12891,34 @@ function attachReplayPlane(deps) {
12792
12891
  const currentGrain = () => autoGrain ? "auto" : manualGrain ?? "auto";
12793
12892
  const paintCursor = () => {
12794
12893
  if (!master) return;
12894
+ stopGlide();
12795
12895
  deps.paint(master.slice(0, cursor));
12796
12896
  deps.chart.timeScale().scrollToRealTime();
12797
12897
  };
12798
12898
  const paintForming = () => {
12799
12899
  if (!master || !subs) return;
12900
+ stopGlide();
12800
12901
  const parent = master[cursor - 1];
12801
12902
  deps.paint([...master.slice(0, cursor - 1), composeFormingBar(parent, subs, formK)]);
12802
12903
  deps.chart.timeScale().scrollToRealTime();
12803
12904
  };
12905
+ const paintStart = () => {
12906
+ if (!master) return;
12907
+ const scale = deps.chart.timeScale();
12908
+ const shown2 = scale.getVisibleRange();
12909
+ const view = scale.getVisibleLogicalRange();
12910
+ const chosen = master[cursor - 1].t;
12911
+ const from = shown2?.from;
12912
+ const to = shown2?.to;
12913
+ if (!view || typeof from !== "number" || typeof to !== "number" || chosen < from || chosen > to) return paintCursor();
12914
+ stopGlide();
12915
+ deps.paint(master.slice(0, cursor));
12916
+ scale.setVisibleLogicalRange(view);
12917
+ glide = setTimeout(() => {
12918
+ glide = null;
12919
+ if (master && !destroyed && !deps.disposed()) scale.scrollToRealTime();
12920
+ }, START_HOLD_MS);
12921
+ };
12804
12922
  const stopTimer = () => {
12805
12923
  if (timer) {
12806
12924
  clearInterval(timer);
@@ -12884,6 +13002,7 @@ function attachReplayPlane(deps) {
12884
13002
  };
12885
13003
  function abandon() {
12886
13004
  invalidateStep();
13005
+ stopGlide();
12887
13006
  if (!master) return;
12888
13007
  stopTimer();
12889
13008
  playing = false;
@@ -12911,7 +13030,7 @@ function attachReplayPlane(deps) {
12911
13030
  const idx = master.findIndex((b) => b.t >= atSec);
12912
13031
  cursor = Math.max(2, (idx === -1 ? master.length - 1 : idx) + 1);
12913
13032
  deps.setHeader(true);
12914
- paintCursor();
13033
+ paintStart();
12915
13034
  sync();
12916
13035
  },
12917
13036
  exit() {
@@ -13434,7 +13553,7 @@ function attachExtensionsPlane(deps) {
13434
13553
  },
13435
13554
  lockPanZoom: (locked) => {
13436
13555
  if (deps.disposed()) return;
13437
- const state = pointerLock(locked);
13556
+ const state = pointerLock(locked, deps.navigable);
13438
13557
  deps.chart.applyOptions({ handleScroll: state.handleScroll, handleScale: state.handleScale });
13439
13558
  deps.setTouchAction(state.touchAction);
13440
13559
  }
@@ -15943,10 +16062,11 @@ function registerChartCommands(deps) {
15943
16062
  });
15944
16063
  add({ id: "chart.view.reset", scope: "chart", label: "command.viewReset", shortcut: "Alt+KeyR", available: always, execute: () => handle.reset() });
15945
16064
  add({ id: "chart.view.goLive", scope: "chart", label: "command.viewGoLive", shortcut: "Alt+KeyL", available: always, execute: () => handle.goLive() });
15946
- add({ id: "chart.view.zoomIn", scope: "chart", label: "command.viewZoomIn", shortcut: "Equal", available: always, execute: () => deps.zoom("in") });
15947
- add({ id: "chart.view.zoomOut", scope: "chart", label: "command.viewZoomOut", shortcut: "Minus", available: always, execute: () => deps.zoom("out") });
15948
- add({ id: "chart.view.scrollLeft", scope: "chart", label: "command.viewScrollLeft", shortcut: "ArrowLeft", available: always, execute: () => deps.scroll("left") });
15949
- add({ id: "chart.view.scrollRight", scope: "chart", label: "command.viewScrollRight", shortcut: "ArrowRight", available: always, execute: () => deps.scroll("right") });
16065
+ const navigable = () => features.navigation;
16066
+ add({ id: "chart.view.zoomIn", scope: "chart", label: "command.viewZoomIn", shortcut: "Equal", available: navigable, execute: () => deps.zoom("in") });
16067
+ add({ id: "chart.view.zoomOut", scope: "chart", label: "command.viewZoomOut", shortcut: "Minus", available: navigable, execute: () => deps.zoom("out") });
16068
+ add({ id: "chart.view.scrollLeft", scope: "chart", label: "command.viewScrollLeft", shortcut: "ArrowLeft", available: navigable, execute: () => deps.scroll("left") });
16069
+ add({ id: "chart.view.scrollRight", scope: "chart", label: "command.viewScrollRight", shortcut: "ArrowRight", available: navigable, execute: () => deps.scroll("right") });
15950
16070
  add({
15951
16071
  id: "chart.data.download",
15952
16072
  scope: "chart",
@@ -16750,14 +16870,21 @@ function createChartInstance(deps) {
16750
16870
  vertLines: { color: canvas().grid, visible: eff.appearance.grid },
16751
16871
  horzLines: { color: canvas().grid, visible: eff.appearance.grid }
16752
16872
  },
16753
- crosshair: { mode: deps.features.crosshair ? CrosshairMode.Normal : CrosshairMode.Hidden },
16873
+ crosshair: {
16874
+ mode: deps.ui.crosshair ? CrosshairMode.Normal : CrosshairMode.Hidden,
16875
+ vertLine: { labelVisible: deps.ui.crosshairLabels, ...deps.ui.crosshairSolid ? { style: LineStyle3.Solid } : {} },
16876
+ horzLine: { visible: deps.ui.crosshairHorizontal, labelVisible: deps.ui.crosshairLabels, ...deps.ui.crosshairSolid ? { style: LineStyle3.Solid } : {} }
16877
+ },
16754
16878
  // A finger held on the plot scrubs the crosshair for as long as it stays down, and lifting it
16755
16879
  // takes the crosshair away, so the next one-finger drag pans: the way a native chart reads.
16756
16880
  trackingMode: { exitMode: TrackingModeExitMode.OnTouchEnd },
16757
16881
  // The renderer's own momentum throws a flick as fast as seven pixels a millisecond and coasts
16758
16882
  // it thousands of pixels; the chart coasts a flick itself, calmly.
16759
16883
  kineticScroll: { touch: false, mouse: false },
16760
- rightPriceScale: { borderVisible: false, scaleMargins: { top: 0.08, bottom: 0.08 } },
16884
+ // A chart that holds its view takes no drag, wheel, pinch or scale gesture from the renderer.
16885
+ handleScroll: deps.features.navigation,
16886
+ handleScale: deps.features.navigation,
16887
+ rightPriceScale: { visible: deps.ui.priceScale, borderVisible: false, scaleMargins: { top: 0.08, bottom: 0.08 } },
16761
16888
  timeScale: { borderVisible: false, timeVisible: true, secondsVisible: false, rightOffset: 4, barSpacing: 8, minBarSpacing: 0.5 }
16762
16889
  });
16763
16890
  const anchor = chart.addSeries(LineSeries4, {
@@ -16766,7 +16893,13 @@ function createChartInstance(deps) {
16766
16893
  priceLineVisible: false,
16767
16894
  crosshairMarkerVisible: false
16768
16895
  });
16769
- let series2 = addStyleSeries(chart, style, paint());
16896
+ const addMainSeries = (id) => {
16897
+ const added = addStyleSeries(chart, id, paint());
16898
+ if (!deps.ui.priceScale) added.applyOptions({ priceLineVisible: false, lastValueVisible: false });
16899
+ return added;
16900
+ };
16901
+ let series2 = addMainSeries(style);
16902
+ let morph = null;
16770
16903
  const baselineLevel = createBaselineLevel({ paneHeight: () => chart.paneSize().height });
16771
16904
  if (style === "baseline") baselineLevel.follow(series2);
16772
16905
  const volume2 = chart.addSeries(HistogramSeries2, {
@@ -16897,15 +17030,17 @@ function createChartInstance(deps) {
16897
17030
  const crosshairSubs = /* @__PURE__ */ new Set();
16898
17031
  const timeClickSubs = /* @__PURE__ */ new Set();
16899
17032
  const rangeSubs = /* @__PURE__ */ new Set();
17033
+ const reducedMotion = () => gestures.ownerDocument.defaultView?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
16900
17034
  const ranges = createRangeApi({
16901
17035
  chart,
16902
17036
  disposed: disposedFn,
16903
17037
  muted,
16904
17038
  mirrored,
16905
17039
  onGlide: () => followLiveEdge(),
16906
- reducedMotion: () => gestures.ownerDocument.defaultView?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false
17040
+ reducedMotion
16907
17041
  });
16908
- const fling = attachFling({ chart, target: gestures });
17042
+ const still = { stop: () => void 0, destroy: () => void 0 };
17043
+ const fling = deps.features.navigation ? attachFling({ chart, target: gestures }) : still;
16909
17044
  let unregisterRangeMirror = () => void 0;
16910
17045
  function applyTimezone() {
16911
17046
  if (disposed) return;
@@ -17013,6 +17148,7 @@ function createChartInstance(deps) {
17013
17148
  const drawings2 = attachDrawingsPlane({
17014
17149
  chart,
17015
17150
  series: anchor,
17151
+ navigable: deps.features.navigation,
17016
17152
  container: gestures,
17017
17153
  chrome: chrome2,
17018
17154
  chartId: deps.id,
@@ -17086,7 +17222,7 @@ function createChartInstance(deps) {
17086
17222
  setHeader: () => legend2.setHeader(symbol, tf),
17087
17223
  // A chart whose crosshair the host switched OFF keeps it off: replay may take the crosshair
17088
17224
  // away for the length of a question, never hand one back that was never there.
17089
- setCrosshair: (visible) => chart.applyOptions({ crosshair: { mode: visible && deps.features.crosshair ? CrosshairMode.Normal : CrosshairMode.Hidden } }),
17225
+ setCrosshair: (visible) => chart.applyOptions({ crosshair: { mode: visible && deps.ui.crosshair ? CrosshairMode.Normal : CrosshairMode.Hidden } }),
17090
17226
  // The feed's own grains: a chart never offers, or fetches, a timeframe its feed cannot serve.
17091
17227
  resolutions: () => deps.capabilities().resolutions,
17092
17228
  persist: (key, value) => storage.set(key === "speed" ? REPLAY_SPEED_KEY : REPLAY_TIMEFRAME_KEY, value),
@@ -17120,6 +17256,7 @@ function createChartInstance(deps) {
17120
17256
  const extensions = attachExtensionsPlane({
17121
17257
  chartId: deps.id,
17122
17258
  chart,
17259
+ navigable: deps.features.navigation,
17123
17260
  series: () => anchor,
17124
17261
  visible: () => series2,
17125
17262
  gestures,
@@ -17227,8 +17364,8 @@ function createChartInstance(deps) {
17227
17364
  navigationRoot.addEventListener("mouseup", onNativeDragEnd, { passive: true });
17228
17365
  navigationRoot.addEventListener("pointerup", onNativeDragEnd, { passive: true });
17229
17366
  navigationRoot.addEventListener("pointercancel", onNativeDragEnd, { passive: true });
17230
- const pinch = attachPinch({ chart, target: gestures });
17231
- const freePan = deps.freePan ? attachFreePan({
17367
+ const pinch = deps.features.navigation ? attachPinch({ chart, target: gestures }) : null;
17368
+ const freePan = deps.freePan && deps.features.navigation ? attachFreePan({
17232
17369
  chart,
17233
17370
  target: gestures,
17234
17371
  framing: () => priceAxisPolicy() === "auto",
@@ -17252,9 +17389,11 @@ function createChartInstance(deps) {
17252
17389
  const painted = shownBars();
17253
17390
  const values = painted.map((b) => ({ time: b.t, value: b.c }));
17254
17391
  anchor.setData(values);
17255
- series2.setData(
17256
- shaped ? values : painted.map((b) => ({ time: b.t, open: b.o, high: b.h, low: b.l, close: b.c }))
17257
- );
17392
+ if (morph?.bars !== series2) {
17393
+ series2.setData(
17394
+ shaped ? values : painted.map((b) => ({ time: b.t, open: b.o, high: b.h, low: b.l, close: b.c }))
17395
+ );
17396
+ }
17258
17397
  if (volumeInstance()) paintVolume();
17259
17398
  indicators2.recompute();
17260
17399
  compare?.sync();
@@ -17580,20 +17719,48 @@ function createChartInstance(deps) {
17580
17719
  function setStyle(next) {
17581
17720
  if (disposed || next === style || !deps.styles.includes(next)) return;
17582
17721
  const keep = chart.timeScale().getVisibleLogicalRange();
17722
+ morph?.run.finish();
17583
17723
  const previous = series2;
17724
+ const previousStyle = style;
17584
17725
  style = next;
17585
17726
  storage.set(STYLE_KEY, next);
17586
- series2 = addStyleSeries(chart, next, paint());
17727
+ series2 = addMainSeries(next);
17587
17728
  baselineLevel.follow(next === "baseline" ? series2 : null);
17588
17729
  countdown?.seriesChanged(previous);
17589
17730
  extensions.visibleSeriesReplaced();
17590
17731
  applyPriceFormat();
17591
- try {
17592
- chart.removeSeries(previous);
17593
- } catch {
17594
- }
17732
+ const remove = (leaving) => {
17733
+ try {
17734
+ chart.removeSeries(leaving);
17735
+ } catch {
17736
+ }
17737
+ };
17738
+ const folding = valueShaped(next) && !valueShaped(previousStyle);
17739
+ const unfolding = !valueShaped(next) && valueShaped(previousStyle);
17740
+ const morphing = !!deps.styleMorph && (folding || unfolding) && !reducedMotion();
17741
+ if (!morphing) remove(previous);
17595
17742
  paintAll();
17596
17743
  if (keep) chart.timeScale().setVisibleLogicalRange(keep);
17744
+ if (morphing) {
17745
+ const bars2 = folding ? previous : series2;
17746
+ const line2 = folding ? series2 : previous;
17747
+ const lineStyle2 = folding ? next : previousStyle;
17748
+ const entry = {
17749
+ bars: bars2,
17750
+ run: startStyleMorph({
17751
+ bars: bars2,
17752
+ fadeLine: (alpha) => line2.applyOptions(fadedStyleOptions(lineStyle2, paint(), alpha)),
17753
+ shown: shownBars,
17754
+ direction: folding ? "fold" : "unfold",
17755
+ done: () => {
17756
+ if (morph === entry) morph = null;
17757
+ remove(previous);
17758
+ if (folding) line2.applyOptions(styleOptions(lineStyle2, paint()));
17759
+ }
17760
+ })
17761
+ };
17762
+ morph = entry;
17763
+ }
17597
17764
  events.emit("style", next);
17598
17765
  }
17599
17766
  function content() {
@@ -18005,8 +18172,9 @@ function createChartInstance(deps) {
18005
18172
  countdownClock.destroy();
18006
18173
  pointer?.destroy();
18007
18174
  ranges.stopGlide();
18175
+ morph?.run.finish();
18008
18176
  fling.destroy();
18009
- pinch.destroy();
18177
+ pinch?.destroy();
18010
18178
  freePan?.destroy();
18011
18179
  plotArea.destroy();
18012
18180
  extensions.destroy();
@@ -23100,6 +23268,7 @@ function createChart(options) {
23100
23268
  container: element,
23101
23269
  hostContainer: options.container,
23102
23270
  freePan: options.touch?.freePan === true,
23271
+ styleMorph: options.transitions?.style === true,
23103
23272
  layer,
23104
23273
  datafeed: options.datafeed,
23105
23274
  externalDrawingToolbar: !!options.drawingToolbarContainer,