@turtleclub/ui 0.7.0-beta.3 → 0.7.0-beta.30
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/.turbo/turbo-build.log +143 -132
- package/CHANGELOG.md +152 -0
- package/dist/index.cjs +76 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36068 -17674
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/components/charts/area-chart.d.ts +108 -0
- package/dist/types/components/charts/area-chart.d.ts.map +1 -0
- package/dist/types/components/charts/bar-chart.d.ts +110 -0
- package/dist/types/components/charts/bar-chart.d.ts.map +1 -0
- package/dist/types/components/charts/index.d.ts +5 -0
- package/dist/types/components/charts/index.d.ts.map +1 -0
- package/dist/types/components/charts/pie-chart.d.ts +94 -0
- package/dist/types/components/charts/pie-chart.d.ts.map +1 -0
- package/dist/types/components/charts/radial-chart.d.ts +151 -0
- package/dist/types/components/charts/radial-chart.d.ts.map +1 -0
- package/dist/types/components/features/data-table/data-table.d.ts +7 -4
- package/dist/types/components/features/data-table/data-table.d.ts.map +1 -1
- package/dist/types/components/features/data-table/sort-dropdown.d.ts.map +1 -1
- package/dist/types/components/features/search-bar.d.ts +1 -0
- package/dist/types/components/features/search-bar.d.ts.map +1 -1
- package/dist/types/components/molecules/swap-input.d.ts +3 -0
- package/dist/types/components/molecules/swap-input.d.ts.map +1 -1
- package/dist/types/components/molecules/token-selector.d.ts +2 -1
- package/dist/types/components/molecules/token-selector.d.ts.map +1 -1
- package/dist/types/components/ui/avatar.d.ts +2 -2
- package/dist/types/components/ui/avatar.d.ts.map +1 -1
- package/dist/types/components/ui/chart.d.ts +18 -4
- package/dist/types/components/ui/chart.d.ts.map +1 -1
- package/dist/types/components/ui/combobox.d.ts +21 -0
- package/dist/types/components/ui/combobox.d.ts.map +1 -1
- package/dist/types/components/ui/dialog.d.ts.map +1 -1
- package/dist/types/components/ui/dropdown.d.ts +2 -1
- package/dist/types/components/ui/dropdown.d.ts.map +1 -1
- package/dist/types/components/ui/index.d.ts +1 -0
- package/dist/types/components/ui/index.d.ts.map +1 -1
- package/dist/types/components/ui/multi-select.d.ts.map +1 -1
- package/dist/types/components/ui/segment-control.d.ts +1 -0
- package/dist/types/components/ui/segment-control.d.ts.map +1 -1
- package/dist/types/components/ui/slider.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/components/charts/QUICK_REFERENCE.md +323 -0
- package/src/components/charts/README.md +658 -0
- package/src/components/charts/RECHARTS_FEATURES.md +458 -0
- package/src/components/charts/area-chart.tsx +248 -0
- package/src/components/charts/bar-chart.tsx +362 -0
- package/src/components/charts/index.ts +4 -0
- package/src/components/charts/pie-chart.tsx +277 -0
- package/src/components/charts/radial-chart.tsx +312 -0
- package/src/components/features/data-table/data-table.tsx +136 -125
- package/src/components/features/data-table/sort-dropdown.tsx +8 -11
- package/src/components/features/search-bar.tsx +6 -1
- package/src/components/molecules/swap-input.tsx +44 -30
- package/src/components/molecules/token-selector.tsx +10 -1
- package/src/components/ui/avatar.tsx +8 -15
- package/src/components/ui/chart.tsx +100 -109
- package/src/components/ui/combobox.tsx +150 -137
- package/src/components/ui/dialog.tsx +9 -23
- package/src/components/ui/dropdown.tsx +3 -1
- package/src/components/ui/index.ts +1 -0
- package/src/components/ui/multi-select.tsx +325 -307
- package/src/components/ui/segment-control.tsx +7 -2
- package/src/components/ui/slider.tsx +6 -11
- package/src/index.ts +1 -0
- package/src/styles/globals.css +4 -0
- package/src/styles/themes/semantic.css +26 -56
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
# Chart Components
|
|
2
|
+
|
|
3
|
+
Standardized, reusable chart components built with [Recharts](https://recharts.org/) and fully typed with TypeScript. These components provide a consistent interface for creating beautiful, interactive charts with minimal configuration.
|
|
4
|
+
|
|
5
|
+
**Note:** These components leverage Recharts' native features and props wherever possible, including:
|
|
6
|
+
|
|
7
|
+
- Native `Cell` component for per-item styling and conditional coloring
|
|
8
|
+
- Built-in gradient support via `<defs>` and `linearGradient`
|
|
9
|
+
- Native `activeShape`, `activeDot`, and `activeBar` props for hover states
|
|
10
|
+
- Recharts' responsive container system
|
|
11
|
+
- Native accessibility features
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- 🎨 **Consistent Styling** - Uses your theme's CSS variables for colors
|
|
16
|
+
- 📊 **Multiple Chart Types** - Bar, Area, Pie, and Radial charts
|
|
17
|
+
- 🔧 **Fully Typed** - Complete TypeScript support with clear interfaces
|
|
18
|
+
- 🎯 **Easy to Use** - Simple, declarative API
|
|
19
|
+
- 📱 **Responsive** - Automatically adapts to container size
|
|
20
|
+
- ♿ **Accessible** - Built with accessibility in mind
|
|
21
|
+
- 🎨 **Customizable** - Extensive props for customization
|
|
22
|
+
- ⚡ **Native Recharts Features** - Leverages Recharts' built-in capabilities for optimal performance
|
|
23
|
+
|
|
24
|
+
## Available Charts
|
|
25
|
+
|
|
26
|
+
- **BarChart** - Horizontal and vertical bar charts, single or multi-series, stacked
|
|
27
|
+
- **AreaChart** - Smooth area charts with multiple curve types, stacked support
|
|
28
|
+
- **PieChart** - Pie and donut charts with labels and legends
|
|
29
|
+
- **RadialBarChart** - Circular progress indicators
|
|
30
|
+
- **RadarChart** - Multi-dimensional data visualization
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
These components are part of the `@turtleclub/ui` package and depend on `recharts`:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install recharts
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Basic Usage
|
|
41
|
+
|
|
42
|
+
### Bar Chart
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { BarChart } from "@turtleclub/ui";
|
|
46
|
+
import type { ChartConfig } from "@turtleclub/ui";
|
|
47
|
+
|
|
48
|
+
const data = [
|
|
49
|
+
{ month: "Jan", sales: 186 },
|
|
50
|
+
{ month: "Feb", sales: 305 },
|
|
51
|
+
{ month: "Mar", sales: 237 },
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const config = {
|
|
55
|
+
sales: {
|
|
56
|
+
label: "Sales",
|
|
57
|
+
color: "var(--chart-1)",
|
|
58
|
+
},
|
|
59
|
+
} satisfies ChartConfig;
|
|
60
|
+
|
|
61
|
+
function MyChart() {
|
|
62
|
+
return <BarChart data={data} config={config} categoryKey="month" dataKeys={["sales"]} />;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Area Chart
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { AreaChart } from "@turtleclub/ui";
|
|
70
|
+
|
|
71
|
+
const data = [
|
|
72
|
+
{ month: "Jan", revenue: 2400, expenses: 1800 },
|
|
73
|
+
{ month: "Feb", revenue: 1398, expenses: 1200 },
|
|
74
|
+
{ month: "Mar", revenue: 9800, expenses: 2200 },
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
const config = {
|
|
78
|
+
revenue: {
|
|
79
|
+
label: "Revenue",
|
|
80
|
+
color: "var(--chart-1)",
|
|
81
|
+
},
|
|
82
|
+
expenses: {
|
|
83
|
+
label: "Expenses",
|
|
84
|
+
color: "var(--chart-2)",
|
|
85
|
+
},
|
|
86
|
+
} satisfies ChartConfig;
|
|
87
|
+
|
|
88
|
+
function MyChart() {
|
|
89
|
+
return (
|
|
90
|
+
<AreaChart
|
|
91
|
+
data={data}
|
|
92
|
+
config={config}
|
|
93
|
+
categoryKey="month"
|
|
94
|
+
dataKeys={["revenue", "expenses"]}
|
|
95
|
+
showLegend={true}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Pie Chart
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { PieChart } from "@turtleclub/ui";
|
|
105
|
+
|
|
106
|
+
const data = [
|
|
107
|
+
{ category: "electronics", value: 35 },
|
|
108
|
+
{ category: "clothing", value: 25 },
|
|
109
|
+
{ category: "food", value: 20 },
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const config = {
|
|
113
|
+
electronics: { label: "Electronics", color: "var(--chart-1)" },
|
|
114
|
+
clothing: { label: "Clothing", color: "var(--chart-2)" },
|
|
115
|
+
food: { label: "Food", color: "var(--chart-3)" },
|
|
116
|
+
} satisfies ChartConfig;
|
|
117
|
+
|
|
118
|
+
function MyChart() {
|
|
119
|
+
return (
|
|
120
|
+
<PieChart data={data} config={config} nameKey="category" dataKey="value" showLegend={true} />
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Radial Charts
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { RadialBarChart, RadarChart } from "@turtleclub/ui";
|
|
129
|
+
|
|
130
|
+
// Radial Bar Chart (Full Circle)
|
|
131
|
+
const radialData = [
|
|
132
|
+
{ metric: "performance", value: 85, fill: "var(--color-performance)" },
|
|
133
|
+
{ metric: "quality", value: 92, fill: "var(--color-quality)" },
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
const radialConfig = {
|
|
137
|
+
performance: { label: "Performance", color: "var(--chart-1)" },
|
|
138
|
+
quality: { label: "Quality", color: "var(--chart-2)" },
|
|
139
|
+
} satisfies ChartConfig;
|
|
140
|
+
|
|
141
|
+
function MyRadialChart() {
|
|
142
|
+
return (
|
|
143
|
+
<RadialBarChart data={radialData} config={radialConfig} nameKey="metric" dataKey="value" />
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Semi-Circle Radial Chart (Half Circle) - Multiple Values
|
|
148
|
+
const semiCircleData = [
|
|
149
|
+
{ metric: "design", value: 88, fill: "var(--color-design)" },
|
|
150
|
+
{ metric: "development", value: 72, fill: "var(--color-development)" },
|
|
151
|
+
{ metric: "testing", value: 65, fill: "var(--color-testing)" },
|
|
152
|
+
{ metric: "deployment", value: 45, fill: "var(--color-deployment)" },
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
const semiCircleConfig = {
|
|
156
|
+
design: { label: "Design", color: "var(--chart-1)" },
|
|
157
|
+
development: { label: "Development", color: "var(--chart-2)" },
|
|
158
|
+
testing: { label: "Testing", color: "var(--chart-3)" },
|
|
159
|
+
deployment: { label: "Deployment", color: "var(--chart-4)" },
|
|
160
|
+
} satisfies ChartConfig;
|
|
161
|
+
|
|
162
|
+
function MySemiCircleChart() {
|
|
163
|
+
return (
|
|
164
|
+
<RadialBarChart
|
|
165
|
+
data={semiCircleData}
|
|
166
|
+
config={semiCircleConfig}
|
|
167
|
+
nameKey="metric"
|
|
168
|
+
dataKey="value"
|
|
169
|
+
startAngle={180}
|
|
170
|
+
endAngle={0}
|
|
171
|
+
innerRadius={60}
|
|
172
|
+
outerRadius={80}
|
|
173
|
+
/>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Radar Chart
|
|
178
|
+
const radarData = [
|
|
179
|
+
{ skill: "coding", current: 85, target: 90 },
|
|
180
|
+
{ skill: "design", current: 70, target: 85 },
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
const radarConfig = {
|
|
184
|
+
current: { label: "Current", color: "var(--chart-1)" },
|
|
185
|
+
target: { label: "Target", color: "var(--chart-2)" },
|
|
186
|
+
} satisfies ChartConfig;
|
|
187
|
+
|
|
188
|
+
function MyRadarChart() {
|
|
189
|
+
return (
|
|
190
|
+
<RadarChart
|
|
191
|
+
data={radarData}
|
|
192
|
+
config={radarConfig}
|
|
193
|
+
categoryKey="skill"
|
|
194
|
+
dataKeys={["current", "target"]}
|
|
195
|
+
/>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## ChartConfig
|
|
201
|
+
|
|
202
|
+
All charts require a `config` object that defines the styling and labels for your data. The config uses CSS variables from your theme:
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
const config = {
|
|
206
|
+
// For data series
|
|
207
|
+
sales: {
|
|
208
|
+
label: "Sales",
|
|
209
|
+
color: "var(--chart-1)", // Use theme colors
|
|
210
|
+
},
|
|
211
|
+
// For categories (optional label override)
|
|
212
|
+
january: {
|
|
213
|
+
label: "Jan",
|
|
214
|
+
},
|
|
215
|
+
} satisfies ChartConfig;
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Theme Colors
|
|
219
|
+
|
|
220
|
+
Use these CSS variables in your config:
|
|
221
|
+
|
|
222
|
+
- `var(--chart-1)` - Primary chart color
|
|
223
|
+
- `var(--chart-2)` - Secondary chart color
|
|
224
|
+
- `var(--chart-3)` - Tertiary chart color
|
|
225
|
+
- `var(--chart-4)` - Quaternary chart color
|
|
226
|
+
- `var(--chart-5)` - Quinary chart color
|
|
227
|
+
|
|
228
|
+
## Recharts Native Features
|
|
229
|
+
|
|
230
|
+
These components are designed to leverage Recharts' native features for optimal performance and flexibility:
|
|
231
|
+
|
|
232
|
+
### Cell Component (Used in BarChart, PieChart, RadialBarChart)
|
|
233
|
+
|
|
234
|
+
The `Cell` component allows per-item customization of chart elements. Our components use this for:
|
|
235
|
+
|
|
236
|
+
- Conditional coloring based on data values
|
|
237
|
+
- Per-segment styling in pie charts
|
|
238
|
+
- Individual bar coloring in bar charts
|
|
239
|
+
|
|
240
|
+
Example with conditional coloring:
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
<BarChart
|
|
244
|
+
data={data}
|
|
245
|
+
config={config}
|
|
246
|
+
categoryKey="month"
|
|
247
|
+
dataKeys={["sales"]}
|
|
248
|
+
getBarColor={(entry, index, dataKey) => {
|
|
249
|
+
// Color bars differently based on value
|
|
250
|
+
return entry.sales > 200 ? "hsl(var(--destructive))" : undefined;
|
|
251
|
+
}}
|
|
252
|
+
/>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Native Gradient Support
|
|
256
|
+
|
|
257
|
+
All charts use Recharts' native `<defs>` and `linearGradient` for gradient fills:
|
|
258
|
+
|
|
259
|
+
- **BarChart**: Gradients adapt to chart orientation (vertical/horizontal)
|
|
260
|
+
- **AreaChart**: Top-to-bottom gradients for filled areas
|
|
261
|
+
- **PieChart**: Radial gradients from center outward
|
|
262
|
+
- **RadialBarChart**: Radial gradients for circular progress
|
|
263
|
+
|
|
264
|
+
### Active States
|
|
265
|
+
|
|
266
|
+
Recharts provides built-in hover/active states:
|
|
267
|
+
|
|
268
|
+
- `activeShape` prop for custom active rendering
|
|
269
|
+
- `activeDot` prop for highlighting data points
|
|
270
|
+
- `activeBar` prop for bar hover effects
|
|
271
|
+
|
|
272
|
+
Example:
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
<AreaChart
|
|
276
|
+
data={data}
|
|
277
|
+
config={config}
|
|
278
|
+
categoryKey="month"
|
|
279
|
+
dataKeys={["revenue"]}
|
|
280
|
+
showDots={true}
|
|
281
|
+
activeDot={{ r: 6, strokeWidth: 2 }}
|
|
282
|
+
/>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### PolarGrid for Radial Lines
|
|
286
|
+
|
|
287
|
+
The `PolarGrid` component provides native support for radial guidelines:
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
<PieChart
|
|
291
|
+
data={data}
|
|
292
|
+
config={config}
|
|
293
|
+
nameKey="category"
|
|
294
|
+
dataKey="value"
|
|
295
|
+
showRadialGrid={true}
|
|
296
|
+
radialGridLines={12}
|
|
297
|
+
/>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## API Reference
|
|
301
|
+
|
|
302
|
+
### BarChart Props
|
|
303
|
+
|
|
304
|
+
| Prop | Type | Default | Description |
|
|
305
|
+
| ------------- | ---------------------------- | ---------------- | --------------------------------------------------------- |
|
|
306
|
+
| `data` | `BarChartData[]` | Required | Array of data objects |
|
|
307
|
+
| `config` | `ChartConfig` | Required | Chart configuration |
|
|
308
|
+
| `categoryKey` | `string` | Required | Key for X-axis categories |
|
|
309
|
+
| `dataKeys` | `string[]` | Required | Array of keys for bars |
|
|
310
|
+
| `layout` | `"horizontal" \| "vertical"` | `"horizontal"` | Chart orientation |
|
|
311
|
+
| `showGrid` | `boolean` | `true` | Show grid lines |
|
|
312
|
+
| `showLegend` | `boolean` | `false` | Show legend |
|
|
313
|
+
| `showTooltip` | `boolean` | `true` | Show tooltip |
|
|
314
|
+
| `stacked` | `boolean` | `false` | Stack bars |
|
|
315
|
+
| `barRadius` | `number` | `5` | Border radius for bars |
|
|
316
|
+
| `gradient` | `boolean` | `false` | Enable gradient fill (uses Recharts native gradients) |
|
|
317
|
+
| `getBarColor` | `function` | `undefined` | Function to conditionally color bars based on data values |
|
|
318
|
+
| `className` | `string` | `undefined` | Custom className |
|
|
319
|
+
| `aspectRatio` | `string` | `"aspect-video"` | Aspect ratio class |
|
|
320
|
+
| `grow` | `boolean` | `false` | Fill parent container |
|
|
321
|
+
|
|
322
|
+
### AreaChart Props
|
|
323
|
+
|
|
324
|
+
| Prop | Type | Default | Description |
|
|
325
|
+
| ------------- | ------------------- | ---------------- | ----------------------------------------------------- |
|
|
326
|
+
| `data` | `AreaChartData[]` | Required | Array of data objects |
|
|
327
|
+
| `config` | `ChartConfig` | Required | Chart configuration |
|
|
328
|
+
| `categoryKey` | `string` | Required | Key for X-axis categories |
|
|
329
|
+
| `dataKeys` | `string[]` | Required | Array of keys for areas |
|
|
330
|
+
| `showGrid` | `boolean` | `true` | Show grid lines |
|
|
331
|
+
| `showLegend` | `boolean` | `false` | Show legend |
|
|
332
|
+
| `showTooltip` | `boolean` | `true` | Show tooltip |
|
|
333
|
+
| `stacked` | `boolean` | `false` | Stack areas |
|
|
334
|
+
| `gradient` | `boolean` | `true` | Enable gradient fill (uses Recharts native gradients) |
|
|
335
|
+
| `activeDot` | `boolean \| object` | `undefined` | Active dot props for hover states (Recharts native) |
|
|
336
|
+
| `showDots` | `boolean` | `false` | Show dots on data points |
|
|
337
|
+
| `grow` | `boolean` | `false` | Fill parent container |
|
|
338
|
+
| `curveType` | `string` | `"monotone"` | Curve interpolation type |
|
|
339
|
+
| `fillOpacity` | `number` | `0.2` | Fill opacity |
|
|
340
|
+
| `strokeWidth` | `number` | `2` | Line stroke width |
|
|
341
|
+
| `showDots` | `boolean` | `false` | Show data point dots |
|
|
342
|
+
| `className` | `string` | `undefined` | Custom className |
|
|
343
|
+
| `aspectRatio` | `string` | `"aspect-video"` | Aspect ratio class |
|
|
344
|
+
|
|
345
|
+
### PieChart Props
|
|
346
|
+
|
|
347
|
+
| Prop | Type | Default | Description |
|
|
348
|
+
| ---------------- | ---------------- | ----------------- | ---------------------------------- |
|
|
349
|
+
| `data` | `PieChartData[]` | Required | Array of data objects |
|
|
350
|
+
| `config` | `ChartConfig` | Required | Chart configuration |
|
|
351
|
+
| `nameKey` | `string` | Required | Key for segment names |
|
|
352
|
+
| `dataKey` | `string` | Required | Key for segment values |
|
|
353
|
+
| `showLegend` | `boolean` | `true` | Show legend |
|
|
354
|
+
| `showTooltip` | `boolean` | `true` | Show tooltip |
|
|
355
|
+
| `showLabels` | `boolean` | `false` | Show segment labels |
|
|
356
|
+
| `innerRadius` | `number` | `0` | Inner radius (0 = pie, >0 = donut) |
|
|
357
|
+
| `outerRadius` | `number` | `80` | Outer radius |
|
|
358
|
+
| `paddingAngle` | `number` | `0` | Padding between segments |
|
|
359
|
+
| `labelFormatter` | `function` | `undefined` | Custom label formatter |
|
|
360
|
+
| `className` | `string` | `undefined` | Custom className |
|
|
361
|
+
| `aspectRatio` | `string` | `"aspect-square"` | Aspect ratio class |
|
|
362
|
+
|
|
363
|
+
### RadialBarChart Props
|
|
364
|
+
|
|
365
|
+
| Prop | Type | Default | Description |
|
|
366
|
+
| -------------- | ------------------- | ----------------- | ---------------------- |
|
|
367
|
+
| `data` | `RadialChartData[]` | Required | Array of data objects |
|
|
368
|
+
| `config` | `ChartConfig` | Required | Chart configuration |
|
|
369
|
+
| `nameKey` | `string` | Required | Key for segment names |
|
|
370
|
+
| `dataKey` | `string` | Required | Key for values |
|
|
371
|
+
| `showLegend` | `boolean` | `false` | Show legend |
|
|
372
|
+
| `showTooltip` | `boolean` | `true` | Show tooltip |
|
|
373
|
+
| `innerRadius` | `number` | `30` | Inner radius |
|
|
374
|
+
| `outerRadius` | `number` | `100` | Outer radius |
|
|
375
|
+
| `startAngle` | `number` | `90` | Start angle in degrees |
|
|
376
|
+
| `endAngle` | `number` | `-270` | End angle in degrees |
|
|
377
|
+
| `showLabels` | `boolean` | `false` | Show labels on bars |
|
|
378
|
+
| `cornerRadius` | `number` | `10` | Corner radius for bars |
|
|
379
|
+
| `className` | `string` | `undefined` | Custom className |
|
|
380
|
+
| `aspectRatio` | `string` | `"aspect-square"` | Aspect ratio class |
|
|
381
|
+
|
|
382
|
+
### RadarChart Props
|
|
383
|
+
|
|
384
|
+
| Prop | Type | Default | Description |
|
|
385
|
+
| ------------- | ------------------- | ----------------- | ----------------------------- |
|
|
386
|
+
| `data` | `RadialChartData[]` | Required | Array of data objects |
|
|
387
|
+
| `config` | `ChartConfig` | Required | Chart configuration |
|
|
388
|
+
| `categoryKey` | `string` | Required | Key for categories |
|
|
389
|
+
| `dataKeys` | `string[]` | Required | Array of keys for radar areas |
|
|
390
|
+
| `showLegend` | `boolean` | `false` | Show legend |
|
|
391
|
+
| `showTooltip` | `boolean` | `true` | Show tooltip |
|
|
392
|
+
| `showDots` | `boolean` | `true` | Show data point dots |
|
|
393
|
+
| `fillOpacity` | `number` | `0.6` | Fill opacity |
|
|
394
|
+
| `strokeWidth` | `number` | `2` | Line stroke width |
|
|
395
|
+
| `className` | `string` | `undefined` | Custom className |
|
|
396
|
+
| `aspectRatio` | `string` | `"aspect-square"` | Aspect ratio class |
|
|
397
|
+
|
|
398
|
+
## Advanced Usage
|
|
399
|
+
|
|
400
|
+
### Wrapping in Cards
|
|
401
|
+
|
|
402
|
+
For better presentation, wrap charts in Card components:
|
|
403
|
+
|
|
404
|
+
```tsx
|
|
405
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@turtleclub/ui";
|
|
406
|
+
import { BarChart } from "@turtleclub/ui";
|
|
407
|
+
|
|
408
|
+
function MyChart() {
|
|
409
|
+
return (
|
|
410
|
+
<Card>
|
|
411
|
+
<CardHeader>
|
|
412
|
+
<CardTitle>Monthly Sales</CardTitle>
|
|
413
|
+
<CardDescription>Sales data for Q1 2024</CardDescription>
|
|
414
|
+
</CardHeader>
|
|
415
|
+
<CardContent>
|
|
416
|
+
<BarChart data={data} config={config} categoryKey="month" dataKeys={["sales"]} />
|
|
417
|
+
</CardContent>
|
|
418
|
+
</Card>
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Multi-Series Charts
|
|
424
|
+
|
|
425
|
+
Display multiple data series by passing multiple keys:
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
<BarChart
|
|
429
|
+
data={data}
|
|
430
|
+
config={config}
|
|
431
|
+
categoryKey="month"
|
|
432
|
+
dataKeys={["desktop", "mobile", "tablet"]}
|
|
433
|
+
showLegend={true}
|
|
434
|
+
/>
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Stacked Charts
|
|
438
|
+
|
|
439
|
+
Stack data series on top of each other:
|
|
440
|
+
|
|
441
|
+
```tsx
|
|
442
|
+
<AreaChart
|
|
443
|
+
data={data}
|
|
444
|
+
config={config}
|
|
445
|
+
categoryKey="month"
|
|
446
|
+
dataKeys={["revenue", "expenses"]}
|
|
447
|
+
stacked={true}
|
|
448
|
+
showLegend={true}
|
|
449
|
+
/>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Conditional Bar Coloring
|
|
453
|
+
|
|
454
|
+
Use the `getBarColor` prop to conditionally color bars based on their values. This leverages Recharts' native `Cell` component:
|
|
455
|
+
|
|
456
|
+
```tsx
|
|
457
|
+
const data = [
|
|
458
|
+
{ month: "Jan", sales: 186, target: 200 },
|
|
459
|
+
{ month: "Feb", sales: 305, target: 200 },
|
|
460
|
+
{ month: "Mar", sales: 150, target: 200 },
|
|
461
|
+
];
|
|
462
|
+
|
|
463
|
+
<BarChart
|
|
464
|
+
data={data}
|
|
465
|
+
config={config}
|
|
466
|
+
categoryKey="month"
|
|
467
|
+
dataKeys={["sales"]}
|
|
468
|
+
getBarColor={(entry, index, dataKey) => {
|
|
469
|
+
// Color bars red if below target, green if above
|
|
470
|
+
if (entry.sales < entry.target) {
|
|
471
|
+
return "hsl(var(--destructive))";
|
|
472
|
+
} else if (entry.sales > entry.target) {
|
|
473
|
+
return "hsl(var(--success))";
|
|
474
|
+
}
|
|
475
|
+
// Return undefined to use default color
|
|
476
|
+
return undefined;
|
|
477
|
+
}}
|
|
478
|
+
/>;
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**Multiple data keys with conditional coloring:**
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
<BarChart
|
|
485
|
+
data={data}
|
|
486
|
+
config={config}
|
|
487
|
+
categoryKey="month"
|
|
488
|
+
dataKeys={["desktop", "mobile"]}
|
|
489
|
+
getBarColor={(entry, index, dataKey) => {
|
|
490
|
+
// Different logic per data key
|
|
491
|
+
if (dataKey === "desktop" && entry.desktop > 500) {
|
|
492
|
+
return "hsl(142 76% 36%)"; // Green for high desktop sales
|
|
493
|
+
}
|
|
494
|
+
if (dataKey === "mobile" && entry.mobile < 100) {
|
|
495
|
+
return "hsl(346 87% 43%)"; // Red for low mobile sales
|
|
496
|
+
}
|
|
497
|
+
return undefined; // Use default from config
|
|
498
|
+
}}
|
|
499
|
+
/>
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
**Gradient with conditional transparency:**
|
|
503
|
+
|
|
504
|
+
```tsx
|
|
505
|
+
<BarChart
|
|
506
|
+
data={data}
|
|
507
|
+
config={config}
|
|
508
|
+
categoryKey="month"
|
|
509
|
+
dataKeys={["revenue"]}
|
|
510
|
+
gradient={true}
|
|
511
|
+
getBarColor={(entry, index, dataKey) => {
|
|
512
|
+
// Show low values with reduced opacity
|
|
513
|
+
if (entry.revenue < 1000) {
|
|
514
|
+
return "rgba(var(--chart-1-rgb), 0.3)";
|
|
515
|
+
}
|
|
516
|
+
return undefined; // Use gradient for normal values
|
|
517
|
+
}}
|
|
518
|
+
/>
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Custom Aspect Ratios
|
|
522
|
+
|
|
523
|
+
Change the chart dimensions:
|
|
524
|
+
|
|
525
|
+
```tsx
|
|
526
|
+
<BarChart
|
|
527
|
+
data={data}
|
|
528
|
+
config={config}
|
|
529
|
+
categoryKey="month"
|
|
530
|
+
dataKeys={["sales"]}
|
|
531
|
+
aspectRatio="aspect-square"
|
|
532
|
+
/>
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
Available options: `aspect-square`, `aspect-video`, `aspect-[4/3]`, or any custom Tailwind aspect ratio class.
|
|
536
|
+
|
|
537
|
+
### Donut Charts
|
|
538
|
+
|
|
539
|
+
Create donut charts by setting the inner radius:
|
|
540
|
+
|
|
541
|
+
```tsx
|
|
542
|
+
<PieChart
|
|
543
|
+
data={data}
|
|
544
|
+
config={config}
|
|
545
|
+
nameKey="category"
|
|
546
|
+
dataKey="value"
|
|
547
|
+
innerRadius={60}
|
|
548
|
+
showLegend={true}
|
|
549
|
+
/>
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### Semi-Circle Radial Charts
|
|
553
|
+
|
|
554
|
+
Create half-circle gauges with multiple progress indicators using `startAngle` and `endAngle`:
|
|
555
|
+
|
|
556
|
+
```tsx
|
|
557
|
+
// Semi-circle (180° arc) with multiple metrics
|
|
558
|
+
const data = [
|
|
559
|
+
{ metric: "design", value: 88, fill: "var(--color-design)" },
|
|
560
|
+
{ metric: "development", value: 72, fill: "var(--color-development)" },
|
|
561
|
+
{ metric: "testing", value: 65, fill: "var(--color-testing)" },
|
|
562
|
+
{ metric: "deployment", value: 45, fill: "var(--color-deployment)" },
|
|
563
|
+
];
|
|
564
|
+
|
|
565
|
+
const config = {
|
|
566
|
+
design: { label: "Design", color: "var(--chart-1)" },
|
|
567
|
+
development: { label: "Development", color: "var(--chart-2)" },
|
|
568
|
+
testing: { label: "Testing", color: "var(--chart-3)" },
|
|
569
|
+
deployment: { label: "Deployment", color: "var(--chart-4)" },
|
|
570
|
+
} satisfies ChartConfig;
|
|
571
|
+
|
|
572
|
+
<RadialBarChart
|
|
573
|
+
data={data}
|
|
574
|
+
config={config}
|
|
575
|
+
nameKey="metric"
|
|
576
|
+
dataKey="value"
|
|
577
|
+
startAngle={180}
|
|
578
|
+
endAngle={0}
|
|
579
|
+
innerRadius={60}
|
|
580
|
+
outerRadius={80}
|
|
581
|
+
showLegend={true}
|
|
582
|
+
/>
|
|
583
|
+
|
|
584
|
+
// Three-quarter circle (270° arc)
|
|
585
|
+
<RadialBarChart
|
|
586
|
+
data={data}
|
|
587
|
+
config={config}
|
|
588
|
+
nameKey="metric"
|
|
589
|
+
dataKey="value"
|
|
590
|
+
startAngle={135}
|
|
591
|
+
endAngle={-135}
|
|
592
|
+
/>
|
|
593
|
+
|
|
594
|
+
// Quarter circle (90° arc)
|
|
595
|
+
<RadialBarChart
|
|
596
|
+
data={data}
|
|
597
|
+
config={config}
|
|
598
|
+
nameKey="metric"
|
|
599
|
+
dataKey="value"
|
|
600
|
+
startAngle={180}
|
|
601
|
+
endAngle={90}
|
|
602
|
+
/>
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## Examples
|
|
606
|
+
|
|
607
|
+
See the showcase app at `/components/charts` for comprehensive examples of all chart types with various configurations.
|
|
608
|
+
|
|
609
|
+
## Best Practices
|
|
610
|
+
|
|
611
|
+
1. **Use semantic color variables** - Use `--chart-1` through `--chart-5` for consistency
|
|
612
|
+
2. **Provide clear labels** - Always configure meaningful labels in your ChartConfig
|
|
613
|
+
3. **Keep data clean** - Ensure data keys match your config keys
|
|
614
|
+
4. **Consider accessibility** - Use legends and tooltips for better understanding
|
|
615
|
+
5. **Responsive design** - Charts automatically resize, but consider mobile layout
|
|
616
|
+
6. **Performance** - For large datasets (>100 points), consider data aggregation
|
|
617
|
+
|
|
618
|
+
## TypeScript Support
|
|
619
|
+
|
|
620
|
+
All components are fully typed. Import types as needed:
|
|
621
|
+
|
|
622
|
+
```tsx
|
|
623
|
+
import type { BarChartData, BarChartProps, ChartConfig } from "@turtleclub/ui";
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
## Troubleshooting
|
|
627
|
+
|
|
628
|
+
### Colors not showing
|
|
629
|
+
|
|
630
|
+
Ensure your theme has the chart color variables defined:
|
|
631
|
+
|
|
632
|
+
```css
|
|
633
|
+
:root {
|
|
634
|
+
--chart-1: var(--color-brand-green); /* Primary chart color */
|
|
635
|
+
--chart-2: var(--color-info); /* Secondary chart color */
|
|
636
|
+
--chart-3: var(--color-warning); /* Tertiary chart color */
|
|
637
|
+
--chart-4: var(--color-error); /* Quaternary chart color */
|
|
638
|
+
--chart-5: var(--color-success); /* Quinary chart color */
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Data not appearing
|
|
643
|
+
|
|
644
|
+
Check that:
|
|
645
|
+
|
|
646
|
+
- `dataKeys` match keys in your data objects
|
|
647
|
+
- `categoryKey` matches a key in your data objects
|
|
648
|
+
- Data is properly formatted as an array of objects
|
|
649
|
+
|
|
650
|
+
### TypeScript errors
|
|
651
|
+
|
|
652
|
+
Make sure to use `satisfies ChartConfig` on your config objects:
|
|
653
|
+
|
|
654
|
+
```tsx
|
|
655
|
+
const config = {
|
|
656
|
+
sales: { label: "Sales", color: "hsl(var(--chart-1))" },
|
|
657
|
+
} satisfies ChartConfig;
|
|
658
|
+
```
|