hyperprop-charting-library 0.1.140 → 0.1.142

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.
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ CHART_THEMES: () => CHART_THEMES,
24
+ CHART_THEME_NAMES: () => CHART_THEME_NAMES,
23
25
  FIB_DEFAULT_PALETTE: () => FIB_DEFAULT_PALETTE,
24
26
  POSITION_DEFAULT_COLORS: () => POSITION_DEFAULT_COLORS,
25
27
  SCRIPT_SOURCE_INPUT_VALUES: () => SCRIPT_SOURCE_INPUT_VALUES,
@@ -2655,6 +2657,107 @@ var compileScriptIndicator = (definition) => {
2655
2657
  return plugin;
2656
2658
  };
2657
2659
 
2660
+ // src/themes.ts
2661
+ var CHART_THEMES = {
2662
+ midnight: {
2663
+ name: "midnight",
2664
+ background: "#171717",
2665
+ upColor: "#22ab94",
2666
+ downColor: "#f23645",
2667
+ lineColor: "#2563eb",
2668
+ gridColor: "#2b2f38",
2669
+ gridOpacity: 0.38,
2670
+ axisTextColor: "#dbe4f0",
2671
+ axisLineColor: "#5f646d",
2672
+ crosshairColor: "#94a3b8",
2673
+ crosshairLabelBackground: "#6b6f76",
2674
+ crosshairLabelText: "#e2e8f0",
2675
+ crosshairLabelBorder: "#e2e8f0",
2676
+ watermarkColor: "rgba(226,232,240,0.05)",
2677
+ indicatorTextColor: "#cbd5e1",
2678
+ labelTextColor: "#dbeafe",
2679
+ labelBackground: "#0b1220"
2680
+ },
2681
+ light: {
2682
+ name: "light",
2683
+ background: "#ffffff",
2684
+ upColor: "#22ab94",
2685
+ downColor: "#f23645",
2686
+ lineColor: "#2563eb",
2687
+ gridColor: "#e0e3eb",
2688
+ gridOpacity: 0.9,
2689
+ axisTextColor: "#1f2430",
2690
+ axisLineColor: "#c8ccd6",
2691
+ crosshairColor: "#6b7280",
2692
+ crosshairLabelBackground: "#2a2e39",
2693
+ crosshairLabelText: "#ffffff",
2694
+ crosshairLabelBorder: "#6b7280",
2695
+ watermarkColor: "rgba(19,23,34,0.06)",
2696
+ indicatorTextColor: "#4b5563",
2697
+ labelTextColor: "#ffffff",
2698
+ labelBackground: "#f1f3f8"
2699
+ },
2700
+ brand: {
2701
+ name: "brand",
2702
+ background: "#0b1220",
2703
+ upColor: "#22ab94",
2704
+ downColor: "#f23645",
2705
+ lineColor: "#253cff",
2706
+ gridColor: "#1b2740",
2707
+ gridOpacity: 0.6,
2708
+ axisTextColor: "#c3cee8",
2709
+ axisLineColor: "#34405c",
2710
+ crosshairColor: "#6e85ff",
2711
+ crosshairLabelBackground: "#253cff",
2712
+ crosshairLabelText: "#ffffff",
2713
+ crosshairLabelBorder: "#6e85ff",
2714
+ watermarkColor: "rgba(37,60,255,0.08)",
2715
+ indicatorTextColor: "#a9b8dc",
2716
+ labelTextColor: "#ffffff",
2717
+ labelBackground: "#101a2e"
2718
+ },
2719
+ dark: {
2720
+ name: "dark",
2721
+ background: "#0f0f0f",
2722
+ upColor: "#089981",
2723
+ downColor: "#f23645",
2724
+ lineColor: "#2962ff",
2725
+ gridColor: "#3c3c3c",
2726
+ gridOpacity: 0.5,
2727
+ axisTextColor: "#dbdbdb",
2728
+ axisLineColor: "#424242",
2729
+ crosshairColor: "#9598a1",
2730
+ crosshairLabelBackground: "#3c3c3c",
2731
+ crosshairLabelText: "#dbdbdb",
2732
+ crosshairLabelBorder: "#5d5d5d",
2733
+ watermarkColor: "rgba(219,219,219,0.06)",
2734
+ indicatorTextColor: "#b2b5be",
2735
+ labelTextColor: "#ffffff",
2736
+ labelBackground: "#1a1a1a"
2737
+ },
2738
+ "high-contrast": {
2739
+ name: "high-contrast",
2740
+ background: "#000000",
2741
+ upColor: "#00e5a0",
2742
+ downColor: "#ff4d5e",
2743
+ lineColor: "#4d9fff",
2744
+ gridColor: "#5a5a5a",
2745
+ gridOpacity: 0.7,
2746
+ axisTextColor: "#ffffff",
2747
+ axisLineColor: "#8a8a8a",
2748
+ crosshairColor: "#ffffff",
2749
+ crosshairLabelBackground: "#ffffff",
2750
+ crosshairLabelText: "#000000",
2751
+ crosshairLabelBorder: "#ffffff",
2752
+ watermarkColor: "rgba(255,255,255,0.08)",
2753
+ indicatorTextColor: "#ffffff",
2754
+ labelTextColor: "#000000",
2755
+ labelBackground: "#1a1a1a"
2756
+ }
2757
+ };
2758
+ var CHART_THEME_NAMES = Object.keys(CHART_THEMES);
2759
+ var resolveTheme = (theme) => typeof theme === "string" ? CHART_THEMES[theme] ?? CHART_THEMES.midnight : theme;
2760
+
2658
2761
  // src/options.ts
2659
2762
  var DEFAULT_GRID_OPTIONS = {
2660
2763
  color: "#2b2f38",
@@ -3097,6 +3200,7 @@ function createChart(element, options = {}) {
3097
3200
  let keyboardShortcutHandler = null;
3098
3201
  let lastSelectionSignature = null;
3099
3202
  let magnetMode = "none";
3203
+ let activeThemeName = null;
3100
3204
  let priceScaleMode = "linear";
3101
3205
  let priceScaleInverted = false;
3102
3206
  const PRICE_SCALE_LOG_FLOOR = 1e-9;
@@ -9609,6 +9713,23 @@ function createChart(element, options = {}) {
9609
9713
  window.addEventListener("blur", onWindowBlurMagnet);
9610
9714
  }
9611
9715
  const updateOptions = (nextOptions) => {
9716
+ const THEMED_OPTION_KEYS = [
9717
+ "backgroundColor",
9718
+ "upColor",
9719
+ "downColor",
9720
+ "lineColor",
9721
+ "gridColor",
9722
+ "axisColor",
9723
+ "grid",
9724
+ "axis",
9725
+ "xAxis",
9726
+ "yAxis",
9727
+ "crosshair",
9728
+ "watermark"
9729
+ ];
9730
+ if (THEMED_OPTION_KEYS.some((key) => nextOptions[key] !== void 0) || nextOptions.labels?.indicatorTextColor !== void 0) {
9731
+ activeThemeName = null;
9732
+ }
9612
9733
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
9613
9734
  const previousWidth = width;
9614
9735
  const previousHeight = height;
@@ -9637,6 +9758,30 @@ function createChart(element, options = {}) {
9637
9758
  }
9638
9759
  scheduleDraw();
9639
9760
  };
9761
+ const setTheme = (theme) => {
9762
+ const resolved = resolveTheme(theme);
9763
+ updateOptions({
9764
+ backgroundColor: resolved.background,
9765
+ upColor: resolved.upColor,
9766
+ downColor: resolved.downColor,
9767
+ lineColor: resolved.lineColor,
9768
+ gridColor: resolved.gridColor,
9769
+ grid: { color: resolved.gridColor, opacity: resolved.gridOpacity },
9770
+ axis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9771
+ xAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9772
+ yAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9773
+ crosshair: {
9774
+ color: resolved.crosshairColor,
9775
+ labelBackgroundColor: resolved.crosshairLabelBackground,
9776
+ labelTextColor: resolved.crosshairLabelText,
9777
+ labelBorderColor: resolved.crosshairLabelBorder
9778
+ },
9779
+ watermark: { color: resolved.watermarkColor },
9780
+ labels: { indicatorTextColor: resolved.indicatorTextColor }
9781
+ });
9782
+ activeThemeName = resolved.name;
9783
+ };
9784
+ const getTheme = () => activeThemeName;
9640
9785
  const setChartType = (type) => {
9641
9786
  if (mergedOptions.chartType === type) {
9642
9787
  return;
@@ -10165,6 +10310,8 @@ function createChart(element, options = {}) {
10165
10310
  getMagnetMode,
10166
10311
  setPriceScale,
10167
10312
  getPriceScale,
10313
+ setTheme,
10314
+ getTheme,
10168
10315
  setCompareSeries,
10169
10316
  addCompareSeries,
10170
10317
  removeCompareSeries,
@@ -10195,6 +10342,8 @@ function createChart(element, options = {}) {
10195
10342
  }
10196
10343
  // Annotate the CommonJS export names for ESM import in node:
10197
10344
  0 && (module.exports = {
10345
+ CHART_THEMES,
10346
+ CHART_THEME_NAMES,
10198
10347
  FIB_DEFAULT_PALETTE,
10199
10348
  POSITION_DEFAULT_COLORS,
10200
10349
  SCRIPT_SOURCE_INPUT_VALUES,
@@ -607,6 +607,35 @@ interface CompareSeriesOptions {
607
607
  /** Let this series widen the price scale. Default true. */
608
608
  includeInAutoScale?: boolean;
609
609
  }
610
+ /**
611
+ * A complete chart palette. Hosts otherwise configure a dozen colors one by
612
+ * one and re-push them on every light/dark toggle; a theme is that same set as
613
+ * one object, so `setTheme` is a single call.
614
+ */
615
+ interface ChartTheme {
616
+ name: string;
617
+ background: string;
618
+ upColor: string;
619
+ downColor: string;
620
+ /** Line/area/baseline series color. */
621
+ lineColor: string;
622
+ gridColor: string;
623
+ gridOpacity: number;
624
+ axisTextColor: string;
625
+ axisLineColor: string;
626
+ crosshairColor: string;
627
+ crosshairLabelBackground: string;
628
+ crosshairLabelText: string;
629
+ crosshairLabelBorder: string;
630
+ watermarkColor: string;
631
+ /** Indicator names/values drawn inside the plot and pane legends. */
632
+ indicatorTextColor: string;
633
+ /** Text drawn on colored order/preview pills. */
634
+ labelTextColor: string;
635
+ /** Background for preview labels and pills. */
636
+ labelBackground: string;
637
+ }
638
+ type ChartThemeName = "midnight" | "light" | "brand" | "dark" | "high-contrast";
610
639
  /** Touch ergonomics. Fingers are blunter than a mouse cursor. */
611
640
  interface TouchOptions {
612
641
  /**
@@ -818,6 +847,15 @@ interface ChartInstance {
818
847
  */
819
848
  setPriceScale: (options: Partial<PriceScaleOptions>) => void;
820
849
  getPriceScale: () => PriceScaleOptions;
850
+ /**
851
+ * Apply a whole palette at once — a built-in preset name or your own
852
+ * `ChartTheme`. Replaces the per-color `updateOptions` juggling hosts do on
853
+ * every light/dark toggle. Anything the theme doesn't cover (order-line
854
+ * colors, drawing defaults) is left alone.
855
+ */
856
+ setTheme: (theme: ChartThemeName | ChartTheme) => void;
857
+ /** Name of the last applied theme, or null if colors were set by hand. */
858
+ getTheme: () => string | null;
821
859
  /**
822
860
  * Overlay other instruments on the main pane for comparison. Series are
823
861
  * aligned to the main series by timestamp (last known value carries forward
@@ -1025,6 +1063,19 @@ declare const validateScriptSource: (source: string) => string | null;
1025
1063
  */
1026
1064
  declare const compileScriptIndicator: (definition: ScriptIndicatorDefinition) => IndicatorPlugin;
1027
1065
 
1066
+ /**
1067
+ * Built-in palettes.
1068
+ *
1069
+ * `midnight` is the long-standing default and `light` is its counterpart on a
1070
+ * white surface — same candle colors, so switching surfaces doesn't change how
1071
+ * you read the tape. `brand` tints everything toward Hyperprop blue, `dark` is
1072
+ * a neutral near-black for embedders who want no tint at all, and
1073
+ * `high-contrast` trades subtlety for legibility on projectors and for
1074
+ * low-vision users.
1075
+ */
1076
+ declare const CHART_THEMES: Record<ChartThemeName, ChartTheme>;
1077
+ declare const CHART_THEME_NAMES: ChartThemeName[];
1078
+
1028
1079
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
1029
1080
 
1030
- export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TouchOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };
1081
+ export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TouchOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };
@@ -2623,6 +2623,107 @@ var compileScriptIndicator = (definition) => {
2623
2623
  return plugin;
2624
2624
  };
2625
2625
 
2626
+ // src/themes.ts
2627
+ var CHART_THEMES = {
2628
+ midnight: {
2629
+ name: "midnight",
2630
+ background: "#171717",
2631
+ upColor: "#22ab94",
2632
+ downColor: "#f23645",
2633
+ lineColor: "#2563eb",
2634
+ gridColor: "#2b2f38",
2635
+ gridOpacity: 0.38,
2636
+ axisTextColor: "#dbe4f0",
2637
+ axisLineColor: "#5f646d",
2638
+ crosshairColor: "#94a3b8",
2639
+ crosshairLabelBackground: "#6b6f76",
2640
+ crosshairLabelText: "#e2e8f0",
2641
+ crosshairLabelBorder: "#e2e8f0",
2642
+ watermarkColor: "rgba(226,232,240,0.05)",
2643
+ indicatorTextColor: "#cbd5e1",
2644
+ labelTextColor: "#dbeafe",
2645
+ labelBackground: "#0b1220"
2646
+ },
2647
+ light: {
2648
+ name: "light",
2649
+ background: "#ffffff",
2650
+ upColor: "#22ab94",
2651
+ downColor: "#f23645",
2652
+ lineColor: "#2563eb",
2653
+ gridColor: "#e0e3eb",
2654
+ gridOpacity: 0.9,
2655
+ axisTextColor: "#1f2430",
2656
+ axisLineColor: "#c8ccd6",
2657
+ crosshairColor: "#6b7280",
2658
+ crosshairLabelBackground: "#2a2e39",
2659
+ crosshairLabelText: "#ffffff",
2660
+ crosshairLabelBorder: "#6b7280",
2661
+ watermarkColor: "rgba(19,23,34,0.06)",
2662
+ indicatorTextColor: "#4b5563",
2663
+ labelTextColor: "#ffffff",
2664
+ labelBackground: "#f1f3f8"
2665
+ },
2666
+ brand: {
2667
+ name: "brand",
2668
+ background: "#0b1220",
2669
+ upColor: "#22ab94",
2670
+ downColor: "#f23645",
2671
+ lineColor: "#253cff",
2672
+ gridColor: "#1b2740",
2673
+ gridOpacity: 0.6,
2674
+ axisTextColor: "#c3cee8",
2675
+ axisLineColor: "#34405c",
2676
+ crosshairColor: "#6e85ff",
2677
+ crosshairLabelBackground: "#253cff",
2678
+ crosshairLabelText: "#ffffff",
2679
+ crosshairLabelBorder: "#6e85ff",
2680
+ watermarkColor: "rgba(37,60,255,0.08)",
2681
+ indicatorTextColor: "#a9b8dc",
2682
+ labelTextColor: "#ffffff",
2683
+ labelBackground: "#101a2e"
2684
+ },
2685
+ dark: {
2686
+ name: "dark",
2687
+ background: "#0f0f0f",
2688
+ upColor: "#089981",
2689
+ downColor: "#f23645",
2690
+ lineColor: "#2962ff",
2691
+ gridColor: "#3c3c3c",
2692
+ gridOpacity: 0.5,
2693
+ axisTextColor: "#dbdbdb",
2694
+ axisLineColor: "#424242",
2695
+ crosshairColor: "#9598a1",
2696
+ crosshairLabelBackground: "#3c3c3c",
2697
+ crosshairLabelText: "#dbdbdb",
2698
+ crosshairLabelBorder: "#5d5d5d",
2699
+ watermarkColor: "rgba(219,219,219,0.06)",
2700
+ indicatorTextColor: "#b2b5be",
2701
+ labelTextColor: "#ffffff",
2702
+ labelBackground: "#1a1a1a"
2703
+ },
2704
+ "high-contrast": {
2705
+ name: "high-contrast",
2706
+ background: "#000000",
2707
+ upColor: "#00e5a0",
2708
+ downColor: "#ff4d5e",
2709
+ lineColor: "#4d9fff",
2710
+ gridColor: "#5a5a5a",
2711
+ gridOpacity: 0.7,
2712
+ axisTextColor: "#ffffff",
2713
+ axisLineColor: "#8a8a8a",
2714
+ crosshairColor: "#ffffff",
2715
+ crosshairLabelBackground: "#ffffff",
2716
+ crosshairLabelText: "#000000",
2717
+ crosshairLabelBorder: "#ffffff",
2718
+ watermarkColor: "rgba(255,255,255,0.08)",
2719
+ indicatorTextColor: "#ffffff",
2720
+ labelTextColor: "#000000",
2721
+ labelBackground: "#1a1a1a"
2722
+ }
2723
+ };
2724
+ var CHART_THEME_NAMES = Object.keys(CHART_THEMES);
2725
+ var resolveTheme = (theme) => typeof theme === "string" ? CHART_THEMES[theme] ?? CHART_THEMES.midnight : theme;
2726
+
2626
2727
  // src/options.ts
2627
2728
  var DEFAULT_GRID_OPTIONS = {
2628
2729
  color: "#2b2f38",
@@ -3065,6 +3166,7 @@ function createChart(element, options = {}) {
3065
3166
  let keyboardShortcutHandler = null;
3066
3167
  let lastSelectionSignature = null;
3067
3168
  let magnetMode = "none";
3169
+ let activeThemeName = null;
3068
3170
  let priceScaleMode = "linear";
3069
3171
  let priceScaleInverted = false;
3070
3172
  const PRICE_SCALE_LOG_FLOOR = 1e-9;
@@ -9577,6 +9679,23 @@ function createChart(element, options = {}) {
9577
9679
  window.addEventListener("blur", onWindowBlurMagnet);
9578
9680
  }
9579
9681
  const updateOptions = (nextOptions) => {
9682
+ const THEMED_OPTION_KEYS = [
9683
+ "backgroundColor",
9684
+ "upColor",
9685
+ "downColor",
9686
+ "lineColor",
9687
+ "gridColor",
9688
+ "axisColor",
9689
+ "grid",
9690
+ "axis",
9691
+ "xAxis",
9692
+ "yAxis",
9693
+ "crosshair",
9694
+ "watermark"
9695
+ ];
9696
+ if (THEMED_OPTION_KEYS.some((key) => nextOptions[key] !== void 0) || nextOptions.labels?.indicatorTextColor !== void 0) {
9697
+ activeThemeName = null;
9698
+ }
9580
9699
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
9581
9700
  const previousWidth = width;
9582
9701
  const previousHeight = height;
@@ -9605,6 +9724,30 @@ function createChart(element, options = {}) {
9605
9724
  }
9606
9725
  scheduleDraw();
9607
9726
  };
9727
+ const setTheme = (theme) => {
9728
+ const resolved = resolveTheme(theme);
9729
+ updateOptions({
9730
+ backgroundColor: resolved.background,
9731
+ upColor: resolved.upColor,
9732
+ downColor: resolved.downColor,
9733
+ lineColor: resolved.lineColor,
9734
+ gridColor: resolved.gridColor,
9735
+ grid: { color: resolved.gridColor, opacity: resolved.gridOpacity },
9736
+ axis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9737
+ xAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9738
+ yAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9739
+ crosshair: {
9740
+ color: resolved.crosshairColor,
9741
+ labelBackgroundColor: resolved.crosshairLabelBackground,
9742
+ labelTextColor: resolved.crosshairLabelText,
9743
+ labelBorderColor: resolved.crosshairLabelBorder
9744
+ },
9745
+ watermark: { color: resolved.watermarkColor },
9746
+ labels: { indicatorTextColor: resolved.indicatorTextColor }
9747
+ });
9748
+ activeThemeName = resolved.name;
9749
+ };
9750
+ const getTheme = () => activeThemeName;
9608
9751
  const setChartType = (type) => {
9609
9752
  if (mergedOptions.chartType === type) {
9610
9753
  return;
@@ -10133,6 +10276,8 @@ function createChart(element, options = {}) {
10133
10276
  getMagnetMode,
10134
10277
  setPriceScale,
10135
10278
  getPriceScale,
10279
+ setTheme,
10280
+ getTheme,
10136
10281
  setCompareSeries,
10137
10282
  addCompareSeries,
10138
10283
  removeCompareSeries,
@@ -10162,6 +10307,8 @@ function createChart(element, options = {}) {
10162
10307
  };
10163
10308
  }
10164
10309
  export {
10310
+ CHART_THEMES,
10311
+ CHART_THEME_NAMES,
10165
10312
  FIB_DEFAULT_PALETTE,
10166
10313
  POSITION_DEFAULT_COLORS,
10167
10314
  SCRIPT_SOURCE_INPUT_VALUES,
package/dist/index.cjs CHANGED
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ CHART_THEMES: () => CHART_THEMES,
24
+ CHART_THEME_NAMES: () => CHART_THEME_NAMES,
23
25
  FIB_DEFAULT_PALETTE: () => FIB_DEFAULT_PALETTE,
24
26
  POSITION_DEFAULT_COLORS: () => POSITION_DEFAULT_COLORS,
25
27
  SCRIPT_SOURCE_INPUT_VALUES: () => SCRIPT_SOURCE_INPUT_VALUES,
@@ -2655,6 +2657,107 @@ var compileScriptIndicator = (definition) => {
2655
2657
  return plugin;
2656
2658
  };
2657
2659
 
2660
+ // src/themes.ts
2661
+ var CHART_THEMES = {
2662
+ midnight: {
2663
+ name: "midnight",
2664
+ background: "#171717",
2665
+ upColor: "#22ab94",
2666
+ downColor: "#f23645",
2667
+ lineColor: "#2563eb",
2668
+ gridColor: "#2b2f38",
2669
+ gridOpacity: 0.38,
2670
+ axisTextColor: "#dbe4f0",
2671
+ axisLineColor: "#5f646d",
2672
+ crosshairColor: "#94a3b8",
2673
+ crosshairLabelBackground: "#6b6f76",
2674
+ crosshairLabelText: "#e2e8f0",
2675
+ crosshairLabelBorder: "#e2e8f0",
2676
+ watermarkColor: "rgba(226,232,240,0.05)",
2677
+ indicatorTextColor: "#cbd5e1",
2678
+ labelTextColor: "#dbeafe",
2679
+ labelBackground: "#0b1220"
2680
+ },
2681
+ light: {
2682
+ name: "light",
2683
+ background: "#ffffff",
2684
+ upColor: "#22ab94",
2685
+ downColor: "#f23645",
2686
+ lineColor: "#2563eb",
2687
+ gridColor: "#e0e3eb",
2688
+ gridOpacity: 0.9,
2689
+ axisTextColor: "#1f2430",
2690
+ axisLineColor: "#c8ccd6",
2691
+ crosshairColor: "#6b7280",
2692
+ crosshairLabelBackground: "#2a2e39",
2693
+ crosshairLabelText: "#ffffff",
2694
+ crosshairLabelBorder: "#6b7280",
2695
+ watermarkColor: "rgba(19,23,34,0.06)",
2696
+ indicatorTextColor: "#4b5563",
2697
+ labelTextColor: "#ffffff",
2698
+ labelBackground: "#f1f3f8"
2699
+ },
2700
+ brand: {
2701
+ name: "brand",
2702
+ background: "#0b1220",
2703
+ upColor: "#22ab94",
2704
+ downColor: "#f23645",
2705
+ lineColor: "#253cff",
2706
+ gridColor: "#1b2740",
2707
+ gridOpacity: 0.6,
2708
+ axisTextColor: "#c3cee8",
2709
+ axisLineColor: "#34405c",
2710
+ crosshairColor: "#6e85ff",
2711
+ crosshairLabelBackground: "#253cff",
2712
+ crosshairLabelText: "#ffffff",
2713
+ crosshairLabelBorder: "#6e85ff",
2714
+ watermarkColor: "rgba(37,60,255,0.08)",
2715
+ indicatorTextColor: "#a9b8dc",
2716
+ labelTextColor: "#ffffff",
2717
+ labelBackground: "#101a2e"
2718
+ },
2719
+ dark: {
2720
+ name: "dark",
2721
+ background: "#0f0f0f",
2722
+ upColor: "#089981",
2723
+ downColor: "#f23645",
2724
+ lineColor: "#2962ff",
2725
+ gridColor: "#3c3c3c",
2726
+ gridOpacity: 0.5,
2727
+ axisTextColor: "#dbdbdb",
2728
+ axisLineColor: "#424242",
2729
+ crosshairColor: "#9598a1",
2730
+ crosshairLabelBackground: "#3c3c3c",
2731
+ crosshairLabelText: "#dbdbdb",
2732
+ crosshairLabelBorder: "#5d5d5d",
2733
+ watermarkColor: "rgba(219,219,219,0.06)",
2734
+ indicatorTextColor: "#b2b5be",
2735
+ labelTextColor: "#ffffff",
2736
+ labelBackground: "#1a1a1a"
2737
+ },
2738
+ "high-contrast": {
2739
+ name: "high-contrast",
2740
+ background: "#000000",
2741
+ upColor: "#00e5a0",
2742
+ downColor: "#ff4d5e",
2743
+ lineColor: "#4d9fff",
2744
+ gridColor: "#5a5a5a",
2745
+ gridOpacity: 0.7,
2746
+ axisTextColor: "#ffffff",
2747
+ axisLineColor: "#8a8a8a",
2748
+ crosshairColor: "#ffffff",
2749
+ crosshairLabelBackground: "#ffffff",
2750
+ crosshairLabelText: "#000000",
2751
+ crosshairLabelBorder: "#ffffff",
2752
+ watermarkColor: "rgba(255,255,255,0.08)",
2753
+ indicatorTextColor: "#ffffff",
2754
+ labelTextColor: "#000000",
2755
+ labelBackground: "#1a1a1a"
2756
+ }
2757
+ };
2758
+ var CHART_THEME_NAMES = Object.keys(CHART_THEMES);
2759
+ var resolveTheme = (theme) => typeof theme === "string" ? CHART_THEMES[theme] ?? CHART_THEMES.midnight : theme;
2760
+
2658
2761
  // src/options.ts
2659
2762
  var DEFAULT_GRID_OPTIONS = {
2660
2763
  color: "#2b2f38",
@@ -3097,6 +3200,7 @@ function createChart(element, options = {}) {
3097
3200
  let keyboardShortcutHandler = null;
3098
3201
  let lastSelectionSignature = null;
3099
3202
  let magnetMode = "none";
3203
+ let activeThemeName = null;
3100
3204
  let priceScaleMode = "linear";
3101
3205
  let priceScaleInverted = false;
3102
3206
  const PRICE_SCALE_LOG_FLOOR = 1e-9;
@@ -9609,6 +9713,23 @@ function createChart(element, options = {}) {
9609
9713
  window.addEventListener("blur", onWindowBlurMagnet);
9610
9714
  }
9611
9715
  const updateOptions = (nextOptions) => {
9716
+ const THEMED_OPTION_KEYS = [
9717
+ "backgroundColor",
9718
+ "upColor",
9719
+ "downColor",
9720
+ "lineColor",
9721
+ "gridColor",
9722
+ "axisColor",
9723
+ "grid",
9724
+ "axis",
9725
+ "xAxis",
9726
+ "yAxis",
9727
+ "crosshair",
9728
+ "watermark"
9729
+ ];
9730
+ if (THEMED_OPTION_KEYS.some((key) => nextOptions[key] !== void 0) || nextOptions.labels?.indicatorTextColor !== void 0) {
9731
+ activeThemeName = null;
9732
+ }
9612
9733
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
9613
9734
  const previousWidth = width;
9614
9735
  const previousHeight = height;
@@ -9637,6 +9758,30 @@ function createChart(element, options = {}) {
9637
9758
  }
9638
9759
  scheduleDraw();
9639
9760
  };
9761
+ const setTheme = (theme) => {
9762
+ const resolved = resolveTheme(theme);
9763
+ updateOptions({
9764
+ backgroundColor: resolved.background,
9765
+ upColor: resolved.upColor,
9766
+ downColor: resolved.downColor,
9767
+ lineColor: resolved.lineColor,
9768
+ gridColor: resolved.gridColor,
9769
+ grid: { color: resolved.gridColor, opacity: resolved.gridOpacity },
9770
+ axis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9771
+ xAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9772
+ yAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9773
+ crosshair: {
9774
+ color: resolved.crosshairColor,
9775
+ labelBackgroundColor: resolved.crosshairLabelBackground,
9776
+ labelTextColor: resolved.crosshairLabelText,
9777
+ labelBorderColor: resolved.crosshairLabelBorder
9778
+ },
9779
+ watermark: { color: resolved.watermarkColor },
9780
+ labels: { indicatorTextColor: resolved.indicatorTextColor }
9781
+ });
9782
+ activeThemeName = resolved.name;
9783
+ };
9784
+ const getTheme = () => activeThemeName;
9640
9785
  const setChartType = (type) => {
9641
9786
  if (mergedOptions.chartType === type) {
9642
9787
  return;
@@ -10165,6 +10310,8 @@ function createChart(element, options = {}) {
10165
10310
  getMagnetMode,
10166
10311
  setPriceScale,
10167
10312
  getPriceScale,
10313
+ setTheme,
10314
+ getTheme,
10168
10315
  setCompareSeries,
10169
10316
  addCompareSeries,
10170
10317
  removeCompareSeries,
@@ -10195,6 +10342,8 @@ function createChart(element, options = {}) {
10195
10342
  }
10196
10343
  // Annotate the CommonJS export names for ESM import in node:
10197
10344
  0 && (module.exports = {
10345
+ CHART_THEMES,
10346
+ CHART_THEME_NAMES,
10198
10347
  FIB_DEFAULT_PALETTE,
10199
10348
  POSITION_DEFAULT_COLORS,
10200
10349
  SCRIPT_SOURCE_INPUT_VALUES,
package/dist/index.d.cts CHANGED
@@ -607,6 +607,35 @@ interface CompareSeriesOptions {
607
607
  /** Let this series widen the price scale. Default true. */
608
608
  includeInAutoScale?: boolean;
609
609
  }
610
+ /**
611
+ * A complete chart palette. Hosts otherwise configure a dozen colors one by
612
+ * one and re-push them on every light/dark toggle; a theme is that same set as
613
+ * one object, so `setTheme` is a single call.
614
+ */
615
+ interface ChartTheme {
616
+ name: string;
617
+ background: string;
618
+ upColor: string;
619
+ downColor: string;
620
+ /** Line/area/baseline series color. */
621
+ lineColor: string;
622
+ gridColor: string;
623
+ gridOpacity: number;
624
+ axisTextColor: string;
625
+ axisLineColor: string;
626
+ crosshairColor: string;
627
+ crosshairLabelBackground: string;
628
+ crosshairLabelText: string;
629
+ crosshairLabelBorder: string;
630
+ watermarkColor: string;
631
+ /** Indicator names/values drawn inside the plot and pane legends. */
632
+ indicatorTextColor: string;
633
+ /** Text drawn on colored order/preview pills. */
634
+ labelTextColor: string;
635
+ /** Background for preview labels and pills. */
636
+ labelBackground: string;
637
+ }
638
+ type ChartThemeName = "midnight" | "light" | "brand" | "dark" | "high-contrast";
610
639
  /** Touch ergonomics. Fingers are blunter than a mouse cursor. */
611
640
  interface TouchOptions {
612
641
  /**
@@ -818,6 +847,15 @@ interface ChartInstance {
818
847
  */
819
848
  setPriceScale: (options: Partial<PriceScaleOptions>) => void;
820
849
  getPriceScale: () => PriceScaleOptions;
850
+ /**
851
+ * Apply a whole palette at once — a built-in preset name or your own
852
+ * `ChartTheme`. Replaces the per-color `updateOptions` juggling hosts do on
853
+ * every light/dark toggle. Anything the theme doesn't cover (order-line
854
+ * colors, drawing defaults) is left alone.
855
+ */
856
+ setTheme: (theme: ChartThemeName | ChartTheme) => void;
857
+ /** Name of the last applied theme, or null if colors were set by hand. */
858
+ getTheme: () => string | null;
821
859
  /**
822
860
  * Overlay other instruments on the main pane for comparison. Series are
823
861
  * aligned to the main series by timestamp (last known value carries forward
@@ -1025,6 +1063,19 @@ declare const validateScriptSource: (source: string) => string | null;
1025
1063
  */
1026
1064
  declare const compileScriptIndicator: (definition: ScriptIndicatorDefinition) => IndicatorPlugin;
1027
1065
 
1066
+ /**
1067
+ * Built-in palettes.
1068
+ *
1069
+ * `midnight` is the long-standing default and `light` is its counterpart on a
1070
+ * white surface — same candle colors, so switching surfaces doesn't change how
1071
+ * you read the tape. `brand` tints everything toward Hyperprop blue, `dark` is
1072
+ * a neutral near-black for embedders who want no tint at all, and
1073
+ * `high-contrast` trades subtlety for legibility on projectors and for
1074
+ * low-vision users.
1075
+ */
1076
+ declare const CHART_THEMES: Record<ChartThemeName, ChartTheme>;
1077
+ declare const CHART_THEME_NAMES: ChartThemeName[];
1078
+
1028
1079
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
1029
1080
 
1030
- export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TouchOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };
1081
+ export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TouchOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };
package/dist/index.d.ts CHANGED
@@ -607,6 +607,35 @@ interface CompareSeriesOptions {
607
607
  /** Let this series widen the price scale. Default true. */
608
608
  includeInAutoScale?: boolean;
609
609
  }
610
+ /**
611
+ * A complete chart palette. Hosts otherwise configure a dozen colors one by
612
+ * one and re-push them on every light/dark toggle; a theme is that same set as
613
+ * one object, so `setTheme` is a single call.
614
+ */
615
+ interface ChartTheme {
616
+ name: string;
617
+ background: string;
618
+ upColor: string;
619
+ downColor: string;
620
+ /** Line/area/baseline series color. */
621
+ lineColor: string;
622
+ gridColor: string;
623
+ gridOpacity: number;
624
+ axisTextColor: string;
625
+ axisLineColor: string;
626
+ crosshairColor: string;
627
+ crosshairLabelBackground: string;
628
+ crosshairLabelText: string;
629
+ crosshairLabelBorder: string;
630
+ watermarkColor: string;
631
+ /** Indicator names/values drawn inside the plot and pane legends. */
632
+ indicatorTextColor: string;
633
+ /** Text drawn on colored order/preview pills. */
634
+ labelTextColor: string;
635
+ /** Background for preview labels and pills. */
636
+ labelBackground: string;
637
+ }
638
+ type ChartThemeName = "midnight" | "light" | "brand" | "dark" | "high-contrast";
610
639
  /** Touch ergonomics. Fingers are blunter than a mouse cursor. */
611
640
  interface TouchOptions {
612
641
  /**
@@ -818,6 +847,15 @@ interface ChartInstance {
818
847
  */
819
848
  setPriceScale: (options: Partial<PriceScaleOptions>) => void;
820
849
  getPriceScale: () => PriceScaleOptions;
850
+ /**
851
+ * Apply a whole palette at once — a built-in preset name or your own
852
+ * `ChartTheme`. Replaces the per-color `updateOptions` juggling hosts do on
853
+ * every light/dark toggle. Anything the theme doesn't cover (order-line
854
+ * colors, drawing defaults) is left alone.
855
+ */
856
+ setTheme: (theme: ChartThemeName | ChartTheme) => void;
857
+ /** Name of the last applied theme, or null if colors were set by hand. */
858
+ getTheme: () => string | null;
821
859
  /**
822
860
  * Overlay other instruments on the main pane for comparison. Series are
823
861
  * aligned to the main series by timestamp (last known value carries forward
@@ -1025,6 +1063,19 @@ declare const validateScriptSource: (source: string) => string | null;
1025
1063
  */
1026
1064
  declare const compileScriptIndicator: (definition: ScriptIndicatorDefinition) => IndicatorPlugin;
1027
1065
 
1066
+ /**
1067
+ * Built-in palettes.
1068
+ *
1069
+ * `midnight` is the long-standing default and `light` is its counterpart on a
1070
+ * white surface — same candle colors, so switching surfaces doesn't change how
1071
+ * you read the tape. `brand` tints everything toward Hyperprop blue, `dark` is
1072
+ * a neutral near-black for embedders who want no tint at all, and
1073
+ * `high-contrast` trades subtlety for legibility on projectors and for
1074
+ * low-vision users.
1075
+ */
1076
+ declare const CHART_THEMES: Record<ChartThemeName, ChartTheme>;
1077
+ declare const CHART_THEME_NAMES: ChartThemeName[];
1078
+
1028
1079
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
1029
1080
 
1030
- export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TouchOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };
1081
+ export { type AccessibilityOptions, type AxisOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type KeyboardOptions, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, SCRIPT_SOURCE_INPUT_VALUES, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type TickerLineOptions, type TouchOptions, type TradeMarkerOptions, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, validateScriptSource };
package/dist/index.js CHANGED
@@ -2623,6 +2623,107 @@ var compileScriptIndicator = (definition) => {
2623
2623
  return plugin;
2624
2624
  };
2625
2625
 
2626
+ // src/themes.ts
2627
+ var CHART_THEMES = {
2628
+ midnight: {
2629
+ name: "midnight",
2630
+ background: "#171717",
2631
+ upColor: "#22ab94",
2632
+ downColor: "#f23645",
2633
+ lineColor: "#2563eb",
2634
+ gridColor: "#2b2f38",
2635
+ gridOpacity: 0.38,
2636
+ axisTextColor: "#dbe4f0",
2637
+ axisLineColor: "#5f646d",
2638
+ crosshairColor: "#94a3b8",
2639
+ crosshairLabelBackground: "#6b6f76",
2640
+ crosshairLabelText: "#e2e8f0",
2641
+ crosshairLabelBorder: "#e2e8f0",
2642
+ watermarkColor: "rgba(226,232,240,0.05)",
2643
+ indicatorTextColor: "#cbd5e1",
2644
+ labelTextColor: "#dbeafe",
2645
+ labelBackground: "#0b1220"
2646
+ },
2647
+ light: {
2648
+ name: "light",
2649
+ background: "#ffffff",
2650
+ upColor: "#22ab94",
2651
+ downColor: "#f23645",
2652
+ lineColor: "#2563eb",
2653
+ gridColor: "#e0e3eb",
2654
+ gridOpacity: 0.9,
2655
+ axisTextColor: "#1f2430",
2656
+ axisLineColor: "#c8ccd6",
2657
+ crosshairColor: "#6b7280",
2658
+ crosshairLabelBackground: "#2a2e39",
2659
+ crosshairLabelText: "#ffffff",
2660
+ crosshairLabelBorder: "#6b7280",
2661
+ watermarkColor: "rgba(19,23,34,0.06)",
2662
+ indicatorTextColor: "#4b5563",
2663
+ labelTextColor: "#ffffff",
2664
+ labelBackground: "#f1f3f8"
2665
+ },
2666
+ brand: {
2667
+ name: "brand",
2668
+ background: "#0b1220",
2669
+ upColor: "#22ab94",
2670
+ downColor: "#f23645",
2671
+ lineColor: "#253cff",
2672
+ gridColor: "#1b2740",
2673
+ gridOpacity: 0.6,
2674
+ axisTextColor: "#c3cee8",
2675
+ axisLineColor: "#34405c",
2676
+ crosshairColor: "#6e85ff",
2677
+ crosshairLabelBackground: "#253cff",
2678
+ crosshairLabelText: "#ffffff",
2679
+ crosshairLabelBorder: "#6e85ff",
2680
+ watermarkColor: "rgba(37,60,255,0.08)",
2681
+ indicatorTextColor: "#a9b8dc",
2682
+ labelTextColor: "#ffffff",
2683
+ labelBackground: "#101a2e"
2684
+ },
2685
+ dark: {
2686
+ name: "dark",
2687
+ background: "#0f0f0f",
2688
+ upColor: "#089981",
2689
+ downColor: "#f23645",
2690
+ lineColor: "#2962ff",
2691
+ gridColor: "#3c3c3c",
2692
+ gridOpacity: 0.5,
2693
+ axisTextColor: "#dbdbdb",
2694
+ axisLineColor: "#424242",
2695
+ crosshairColor: "#9598a1",
2696
+ crosshairLabelBackground: "#3c3c3c",
2697
+ crosshairLabelText: "#dbdbdb",
2698
+ crosshairLabelBorder: "#5d5d5d",
2699
+ watermarkColor: "rgba(219,219,219,0.06)",
2700
+ indicatorTextColor: "#b2b5be",
2701
+ labelTextColor: "#ffffff",
2702
+ labelBackground: "#1a1a1a"
2703
+ },
2704
+ "high-contrast": {
2705
+ name: "high-contrast",
2706
+ background: "#000000",
2707
+ upColor: "#00e5a0",
2708
+ downColor: "#ff4d5e",
2709
+ lineColor: "#4d9fff",
2710
+ gridColor: "#5a5a5a",
2711
+ gridOpacity: 0.7,
2712
+ axisTextColor: "#ffffff",
2713
+ axisLineColor: "#8a8a8a",
2714
+ crosshairColor: "#ffffff",
2715
+ crosshairLabelBackground: "#ffffff",
2716
+ crosshairLabelText: "#000000",
2717
+ crosshairLabelBorder: "#ffffff",
2718
+ watermarkColor: "rgba(255,255,255,0.08)",
2719
+ indicatorTextColor: "#ffffff",
2720
+ labelTextColor: "#000000",
2721
+ labelBackground: "#1a1a1a"
2722
+ }
2723
+ };
2724
+ var CHART_THEME_NAMES = Object.keys(CHART_THEMES);
2725
+ var resolveTheme = (theme) => typeof theme === "string" ? CHART_THEMES[theme] ?? CHART_THEMES.midnight : theme;
2726
+
2626
2727
  // src/options.ts
2627
2728
  var DEFAULT_GRID_OPTIONS = {
2628
2729
  color: "#2b2f38",
@@ -3065,6 +3166,7 @@ function createChart(element, options = {}) {
3065
3166
  let keyboardShortcutHandler = null;
3066
3167
  let lastSelectionSignature = null;
3067
3168
  let magnetMode = "none";
3169
+ let activeThemeName = null;
3068
3170
  let priceScaleMode = "linear";
3069
3171
  let priceScaleInverted = false;
3070
3172
  const PRICE_SCALE_LOG_FLOOR = 1e-9;
@@ -9577,6 +9679,23 @@ function createChart(element, options = {}) {
9577
9679
  window.addEventListener("blur", onWindowBlurMagnet);
9578
9680
  }
9579
9681
  const updateOptions = (nextOptions) => {
9682
+ const THEMED_OPTION_KEYS = [
9683
+ "backgroundColor",
9684
+ "upColor",
9685
+ "downColor",
9686
+ "lineColor",
9687
+ "gridColor",
9688
+ "axisColor",
9689
+ "grid",
9690
+ "axis",
9691
+ "xAxis",
9692
+ "yAxis",
9693
+ "crosshair",
9694
+ "watermark"
9695
+ ];
9696
+ if (THEMED_OPTION_KEYS.some((key) => nextOptions[key] !== void 0) || nextOptions.labels?.indicatorTextColor !== void 0) {
9697
+ activeThemeName = null;
9698
+ }
9580
9699
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
9581
9700
  const previousWidth = width;
9582
9701
  const previousHeight = height;
@@ -9605,6 +9724,30 @@ function createChart(element, options = {}) {
9605
9724
  }
9606
9725
  scheduleDraw();
9607
9726
  };
9727
+ const setTheme = (theme) => {
9728
+ const resolved = resolveTheme(theme);
9729
+ updateOptions({
9730
+ backgroundColor: resolved.background,
9731
+ upColor: resolved.upColor,
9732
+ downColor: resolved.downColor,
9733
+ lineColor: resolved.lineColor,
9734
+ gridColor: resolved.gridColor,
9735
+ grid: { color: resolved.gridColor, opacity: resolved.gridOpacity },
9736
+ axis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9737
+ xAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9738
+ yAxis: { textColor: resolved.axisTextColor, lineColor: resolved.axisLineColor },
9739
+ crosshair: {
9740
+ color: resolved.crosshairColor,
9741
+ labelBackgroundColor: resolved.crosshairLabelBackground,
9742
+ labelTextColor: resolved.crosshairLabelText,
9743
+ labelBorderColor: resolved.crosshairLabelBorder
9744
+ },
9745
+ watermark: { color: resolved.watermarkColor },
9746
+ labels: { indicatorTextColor: resolved.indicatorTextColor }
9747
+ });
9748
+ activeThemeName = resolved.name;
9749
+ };
9750
+ const getTheme = () => activeThemeName;
9608
9751
  const setChartType = (type) => {
9609
9752
  if (mergedOptions.chartType === type) {
9610
9753
  return;
@@ -10133,6 +10276,8 @@ function createChart(element, options = {}) {
10133
10276
  getMagnetMode,
10134
10277
  setPriceScale,
10135
10278
  getPriceScale,
10279
+ setTheme,
10280
+ getTheme,
10136
10281
  setCompareSeries,
10137
10282
  addCompareSeries,
10138
10283
  removeCompareSeries,
@@ -10162,6 +10307,8 @@ function createChart(element, options = {}) {
10162
10307
  };
10163
10308
  }
10164
10309
  export {
10310
+ CHART_THEMES,
10311
+ CHART_THEME_NAMES,
10165
10312
  FIB_DEFAULT_PALETTE,
10166
10313
  POSITION_DEFAULT_COLORS,
10167
10314
  SCRIPT_SOURCE_INPUT_VALUES,
package/docs/API.md CHANGED
@@ -568,6 +568,7 @@ an up measurement, red for down.
568
568
  - `cancelDrawing(): boolean` — abort an in-progress multi-click drawing (between the first click and the final point, e.g. a half-drawn trendline/ray/fib). Returns `true` if a draft was cancelled. Wire it to Escape.
569
569
  - Hold **Shift** while drawing or dragging an endpoint of a `trendline`/`ray`/`arrow` to constrain it to the nearest 0/45/90° angle (e.g. a perfectly horizontal line).
570
570
  - `setMagnetMode(mode): void` / `getMagnetMode()` — magnet/snap for all drawing tools. `"none"` off, `"weak"` snaps to a candle's OHLC only when the cursor is near a value, `"strong"` always snaps to the nearest OHLC of the bar under the cursor. Holding Cmd/Ctrl while drawing/dragging forces strong snapping regardless of the mode.
571
+ - `setTheme(theme: ChartThemeName | ChartTheme): void` / `getTheme(): string | null` — apply a whole palette at once; see "Themes" below
571
572
  - `setDatafeed(datafeed: ChartDatafeed | null): Promise<void>` — attach a pull-based data source with lazy history; see "Datafeed" below
572
573
  - `onLongPress(handler: ((event: ChartLongPressEvent) => void) | null): void` — touch press-and-hold inspection
573
574
  - `setCompareSeries(series: CompareSeriesOptions[]): void` / `addCompareSeries(series)` / `removeCompareSeries(id)` / `getCompareSeries()` — overlay other instruments on the main pane; see "Compare overlays" below
@@ -613,6 +614,39 @@ link.click();
613
614
 
614
615
  ---
615
616
 
617
+ ## Themes
618
+
619
+ A theme is the chart's whole palette as one object, so hosts stop setting a
620
+ dozen colors individually and re-pushing them on every light/dark toggle.
621
+
622
+ ```ts
623
+ import { CHART_THEMES, createChart } from "hyperprop-charting-library";
624
+
625
+ chart.setTheme("light"); // built-in preset
626
+ chart.setTheme({ ...CHART_THEMES.dark, upColor: "#00c853" }); // tweak one
627
+ chart.getTheme(); // "light" | null when hand-set
628
+ ```
629
+
630
+ Five presets ship in `CHART_THEMES`:
631
+
632
+ | Preset | Surface | Candles | For |
633
+ | --- | --- | --- | --- |
634
+ | `midnight` | `#171717` | `#22ab94` / `#f23645` | the default dark look |
635
+ | `light` | `#ffffff` | `#22ab94` / `#f23645` | same candles on a white surface |
636
+ | `brand` | `#0b1220` | `#22ab94` / `#f23645` | Hyperprop blue accents (`#253cff`) |
637
+ | `dark` | `#0f0f0f` | `#089981` / `#f23645` | neutral near-black, no tint |
638
+ | `high-contrast` | `#000000` | `#00e5a0` / `#ff4d5e` | projectors, low vision |
639
+
640
+ `setTheme` covers background, candles, the line/area series, grid (color and
641
+ opacity), both axes, the crosshair and its labels, the watermark, and
642
+ indicator legend text. It deliberately does **not** touch order-line colors or
643
+ drawing defaults — those are trading state, not chrome, so switching looks
644
+ never changes what your orders look like mid-session.
645
+
646
+ `getTheme()` returns the active preset name, or `null` once any themed color
647
+ is set by hand. Unrelated `updateOptions` calls (label toggles, sizing, ticker
648
+ line) don't clear it, so it stays a reliable "am I on a preset" signal.
649
+
616
650
  ## Datafeed (optional, pull-based)
617
651
 
618
652
  By default the host pushes bars in with `setData`/`upsertBar`. Attach a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.140",
3
+ "version": "0.1.142",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",