@wick-charts/react 0.2.3 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wick-charts/react",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "High-performance canvas timeseries charts for React — candlestick, line, bar, pie. Tree-shakeable, zero runtime deps.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -49,7 +49,7 @@
49
49
  "react-dom": ">=18.0.0"
50
50
  },
51
51
  "devDependencies": {
52
- "@wick-charts/core": "^0.2.3"
52
+ "@wick-charts/core": "^0.3.0"
53
53
  },
54
54
  "scripts": {
55
55
  "build": "vite build"
@@ -89,13 +89,14 @@ export function CandlestickSeries({ data, options, id: idProp }: CandlestickSeri
89
89
  }
90
90
  }, [
91
91
  chart,
92
- options?.upColor,
93
- options?.downColor,
94
- options?.wickUpColor,
95
- options?.wickDownColor,
92
+ // Tuple bodies are new array refs on every render (preset `autoGradient()`
93
+ // output, inline literals, etc.) and would misfire `Object.is`. Collapse
94
+ // to a stable string the same way BarSeries/LineSeries handle `colors`.
95
+ Array.isArray(options?.up?.body) ? options.up.body.join(',') : options?.up?.body,
96
+ Array.isArray(options?.down?.body) ? options.down.body.join(',') : options?.down?.body,
97
+ options?.up?.wick,
98
+ options?.down?.wick,
96
99
  options?.bodyWidthRatio,
97
- options?.bodyGradient,
98
- options?.candleGradient,
99
100
  options?.entryAnimation,
100
101
  options?.enterAnimation,
101
102
  options?.entryMs,
package/src/index.ts CHANGED
@@ -1,4 +1,12 @@
1
- // Re-export core (users import everything from '@wick-charts/react')
1
+ /**
2
+ * @wick-charts/react — React bindings for Wick Charts.
3
+ *
4
+ * Everything importable from the library is re-exported here: components
5
+ * (`<ChartContainer>`, `<CandlestickSeries>`, …), option types, utility
6
+ * hooks, and themes. The underlying `@wick-charts/core` engine is bundled
7
+ * into this package — its source lives at
8
+ * https://github.com/mo4islona/wick-charts/tree/main/packages/core/src.
9
+ */
2
10
 
3
11
  export type {
4
12
  AxisBound,
@@ -46,6 +54,7 @@ export type {
46
54
  export {
47
55
  ChartInstance,
48
56
  andromeda,
57
+ autoGradient,
49
58
  ayuMirage,
50
59
  buildHoverSnapshots,
51
60
  buildLastSnapshots,
@@ -76,6 +85,9 @@ export {
76
85
  panda,
77
86
  peachCream,
78
87
  quietLight,
88
+ resolveAxisFontSize,
89
+ resolveAxisTextColor,
90
+ resolveCandlestickBodyColor,
79
91
  rosePineDawn,
80
92
  sandDune,
81
93
  solarizedLight,
@@ -18,7 +18,7 @@ export function Crosshair() {
18
18
  // badge from looking like an opaque block.
19
19
  background: `color-mix(in srgb, ${theme.crosshair.labelBackground} 80%, transparent)`,
20
20
  color: theme.crosshair.labelTextColor,
21
- fontSize: theme.typography.axisFontSize,
21
+ fontSize: theme.axis.fontSize,
22
22
  fontFamily: theme.typography.fontFamily,
23
23
  fontVariantNumeric: 'tabular-nums' as const,
24
24
  padding: '2px 6px',
@@ -10,6 +10,7 @@ import {
10
10
  formatCompact,
11
11
  formatPriceAdaptive,
12
12
  formatTime,
13
+ resolveCandlestickBodyColor,
13
14
  } from '@wick-charts/core';
14
15
 
15
16
  import { useChartInstance } from '../context';
@@ -145,7 +146,7 @@ export function InfoBar({ sort = 'none', format = defaultInfoBarFormat, children
145
146
  if (isOHLC) {
146
147
  const ohlc = s.data as OHLCData;
147
148
  const isUp = ohlc.close >= ohlc.open;
148
- const c = isUp ? theme.candlestick.upColor : theme.candlestick.downColor;
149
+ const c = resolveCandlestickBodyColor(isUp ? theme.candlestick.up.body : theme.candlestick.down.body);
149
150
  return (
150
151
  <span key={s.id} style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
151
152
  <LegendItem label="O" display={format(ohlc.open, 'open')} color={c} dim={theme.axis.textColor} />
package/src/ui/Legend.tsx CHANGED
@@ -210,7 +210,7 @@ export function Legend({ items, position = 'bottom', mode = 'toggle', children }
210
210
  alignItems: isRight ? 'flex-start' : 'center',
211
211
  justifyContent: isRight ? 'flex-start' : 'center',
212
212
  fontFamily: theme.typography.fontFamily,
213
- fontSize: theme.typography.axisFontSize,
213
+ fontSize: theme.axis.fontSize,
214
214
  color: theme.axis.textColor,
215
215
  pointerEvents: 'auto',
216
216
  flexShrink: 0,
@@ -136,7 +136,7 @@ export function PieLegend({ seriesId, mode: modeProp, format, position, children
136
136
  // absolute value → dim + smaller.
137
137
  opacity: mode === 'percent' ? 1 : 0.5,
138
138
  fontWeight: mode === 'percent' ? 600 : 400,
139
- fontSize: mode === 'percent' ? theme.typography.fontSize : theme.typography.axisFontSize,
139
+ fontSize: mode === 'percent' ? theme.typography.fontSize : theme.axis.fontSize,
140
140
  fontVariantNumeric: 'tabular-nums',
141
141
  minWidth: 40,
142
142
  textAlign: 'right',
@@ -1,6 +1,6 @@
1
1
  import { type CSSProperties, useMemo } from 'react';
2
2
 
3
- import { type ChartTheme, type TimePoint, formatCompact } from '@wick-charts/core';
3
+ import { type ChartTheme, type TimePoint, formatCompact, resolveCandlestickBodyColor } from '@wick-charts/core';
4
4
 
5
5
  import { BarSeries } from '../BarSeries';
6
6
  import { ChartContainer } from '../ChartContainer';
@@ -85,8 +85,10 @@ export function Sparkline({
85
85
  const change = useMemo(() => computeChange(data), [data]);
86
86
 
87
87
  const resolvedColor = color ?? theme.seriesColors[0];
88
- const resolvedNegColor = negativeColor ?? theme.candlestick.downColor;
89
- const changeColor = change.positive ? theme.candlestick.upColor : theme.candlestick.downColor;
88
+ const resolvedNegColor = negativeColor ?? resolveCandlestickBodyColor(theme.candlestick.down.body);
89
+ const changeColor = resolveCandlestickBodyColor(
90
+ change.positive ? theme.candlestick.up.body : theme.candlestick.down.body,
91
+ );
90
92
 
91
93
  const valueBlock = valuePosition !== 'none' && (
92
94
  <div
@@ -102,7 +104,7 @@ export function Sparkline({
102
104
  {label && (
103
105
  <div
104
106
  style={{
105
- fontSize: theme.typography.axisFontSize,
107
+ fontSize: theme.axis.fontSize,
106
108
  color: theme.axis.textColor,
107
109
  lineHeight: 1.2,
108
110
  whiteSpace: 'nowrap',
@@ -128,7 +130,7 @@ export function Sparkline({
128
130
  {sublabel !== undefined ? (
129
131
  <div
130
132
  style={{
131
- fontSize: theme.typography.axisFontSize - 1,
133
+ fontSize: theme.axis.fontSize - 1,
132
134
  color: theme.axis.textColor,
133
135
  lineHeight: 1.2,
134
136
  whiteSpace: 'nowrap',
@@ -139,7 +141,7 @@ export function Sparkline({
139
141
  ) : (
140
142
  <div
141
143
  style={{
142
- fontSize: theme.typography.axisFontSize - 1,
144
+ fontSize: theme.axis.fontSize - 1,
143
145
  fontWeight: 500,
144
146
  color: changeColor,
145
147
  lineHeight: 1.2,
@@ -1,6 +1,6 @@
1
1
  import { useLayoutEffect, useRef } from 'react';
2
2
 
3
- import { formatTime } from '@wick-charts/core';
3
+ import { formatTime, resolveAxisFontSize, resolveAxisTextColor } from '@wick-charts/core';
4
4
 
5
5
  import { useChartInstance } from '../context';
6
6
  import { useVisibleRange } from '../store-bridge';
@@ -93,8 +93,8 @@ export function TimeAxis({ labelCount, minLabelSpacing }: TimeAxisProps = {}) {
93
93
  position: 'absolute',
94
94
  left: x,
95
95
  transform: 'translateX(-50%)',
96
- color: theme.axis.textColor,
97
- fontSize: theme.typography.axisFontSize,
96
+ color: resolveAxisTextColor(theme, 'x'),
97
+ fontSize: resolveAxisFontSize(theme, 'x'),
98
98
  fontFamily: theme.typography.fontFamily,
99
99
  userSelect: 'none',
100
100
  whiteSpace: 'nowrap',
package/src/ui/Title.tsx CHANGED
@@ -53,7 +53,7 @@ export function Title({ children, sub, style }: TitleProps) {
53
53
  >
54
54
  {children != null && children !== false && <span>{children}</span>}
55
55
  {sub != null && sub !== false && (
56
- <span style={{ fontWeight: 400, color: theme.axis.textColor, fontSize: theme.typography.axisFontSize }}>
56
+ <span style={{ fontWeight: 400, color: theme.axis.textColor, fontSize: theme.axis.fontSize }}>
57
57
  {sub}
58
58
  </span>
59
59
  )}
@@ -12,6 +12,7 @@ import {
12
12
  formatDate,
13
13
  formatPriceAdaptive,
14
14
  formatTime,
15
+ resolveCandlestickBodyColor,
15
16
  } from '@wick-charts/core';
16
17
 
17
18
  export { computeTooltipPosition } from '@wick-charts/core';
@@ -183,7 +184,7 @@ function CustomFloatingTooltip({
183
184
  padding: '10px 14px',
184
185
  boxShadow: '0 4px 16px rgba(0,0,0,0.1), 0 1px 4px rgba(0,0,0,0.06)',
185
186
  fontFamily: theme.typography.fontFamily,
186
- fontSize: theme.typography.tooltipFontSize,
187
+ fontSize: theme.tooltip.fontSize,
187
188
  fontVariantNumeric: 'tabular-nums',
188
189
  color: theme.tooltip.textColor,
189
190
  width: 'max-content',
@@ -245,7 +246,7 @@ function FloatingTooltip({
245
246
  borderRadius: 8,
246
247
  padding: '10px 14px',
247
248
  boxShadow: shadow,
248
- fontSize: theme.typography.tooltipFontSize,
249
+ fontSize: theme.tooltip.fontSize,
249
250
  fontFamily: theme.typography.fontFamily,
250
251
  fontVariantNumeric: 'tabular-nums',
251
252
  color: theme.tooltip.textColor,
@@ -261,7 +262,7 @@ function FloatingTooltip({
261
262
  {/* Time header */}
262
263
  <div
263
264
  style={{
264
- fontSize: theme.typography.axisFontSize,
265
+ fontSize: theme.axis.fontSize,
265
266
  color: theme.axis.textColor,
266
267
  marginBottom: 8,
267
268
  paddingBottom: 6,
@@ -277,9 +278,9 @@ function FloatingTooltip({
277
278
  if (isOHLC) {
278
279
  const ohlc = s.data as OHLCData;
279
280
  const isUp = ohlc.close >= ohlc.open;
280
- const upColor = theme.candlestick.upColor;
281
- const downColor = theme.candlestick.downColor;
282
- const valColor = isUp ? upColor : downColor;
281
+ const valColor = resolveCandlestickBodyColor(
282
+ isUp ? theme.candlestick.up.body : theme.candlestick.down.body,
283
+ );
283
284
  return (
284
285
  <div key={s.id} style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '4px 12px' }}>
285
286
  <TooltipRow label="Open" color={valColor} display={format(ohlc.open, 'open')} />
package/src/ui/YAxis.tsx CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useLayoutEffect, useRef } from 'react';
2
2
 
3
- import type { ValueFormatter } from '@wick-charts/core';
3
+ import { resolveAxisFontSize, resolveAxisTextColor, type ValueFormatter } from '@wick-charts/core';
4
4
 
5
5
  import { useChartInstance } from '../context';
6
6
  import { useYRange } from '../store-bridge';
@@ -103,8 +103,8 @@ export function YAxis({ format, labelCount, minLabelSpacing }: YAxisProps = {})
103
103
  right: 8,
104
104
  top: y,
105
105
  transform: 'translateY(-50%)',
106
- color: theme.axis.textColor,
107
- fontSize: theme.typography.axisFontSize,
106
+ color: resolveAxisTextColor(theme, 'y'),
107
+ fontSize: resolveAxisFontSize(theme, 'y'),
108
108
  fontFamily: theme.typography.fontFamily,
109
109
  fontVariantNumeric: 'tabular-nums',
110
110
  userSelect: 'none',
package/src/ui/YLabel.tsx CHANGED
@@ -152,7 +152,7 @@ export function YLabel({ seriesId, color, format, children }: YLabelProps) {
152
152
  zIndex: 3,
153
153
  background: bgColor,
154
154
  color: theme.yLabel.textColor,
155
- fontSize: theme.typography.yFontSize,
155
+ fontSize: theme.yLabel.fontSize,
156
156
  fontFamily: theme.typography.fontFamily,
157
157
  padding: '3px 8px',
158
158
  borderRadius: 3,