- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
import { useEffect, useState } from "react";
import { CandleChart } from "@gunkin/uiify";
import { CandleChartClient } from "@gunkin/uiify/components/candle-chart/client";
const data = Array.from({ length: 100 }, (_, index) => {
const open = Math.round(24000 + index * 38 + Math.sin(index / 4) * 420);
const close = open + Math.round(Math.sin(index * 1.9) * 190);
return {
time: new Date(Date.UTC(2025, 7, 20 + index)).toISOString().slice(0, 10),
open,
high: Math.max(open, close) + 180,
low: Math.min(open, close) - 160,
close,
};
});
const slotProps = {
caption: {
className:
"absolute z-[1] [inset-block-start:0.75rem] [inset-inline-start:1rem] " +
"text-muted-foreground [font-size:0.75rem] [font-weight:650] " +
"[letter-spacing:0.04em] [text-transform:uppercase]",
},
readout: {
className:
"absolute z-[1] [inset-block-start:0.75rem] [inset-inline-end:1rem] flex " +
"flex-wrap [gap:0.375rem_0.625rem] items-baseline [color:var(--candle-axis)] " +
"[font-size:0.7rem] [font-variant-numeric:tabular-nums] leading-none " +
"whitespace-nowrap",
},
readoutTime: { className: "[font-weight:650]" },
plot: {
className:
"relative grid [grid-template-columns:minmax(0,_1fr)_4.5rem] " +
"[grid-template-rows:minmax(18rem,_1fr)_calc(1.5rem_+_var(--candle-scrollbar-size,_0px))] " +
"[gap:0_0.75rem] [min-inline-size:0] [min-block-size:18rem] " +
"[overscroll-behavior:none]",
},
scrollViewport: {
className:
"[grid-column:1] [grid-row:1_/_span_2] [min-inline-size:0] [min-block-size:18rem] " +
"[overflow:auto_hidden] [container-type:inline-size] [direction:rtl] " +
"group-data-[interactive]/candle-chart:[overscroll-behavior-inline:none]",
},
canvas: {
className:
"grid [grid-template-rows:minmax(18rem,_1fr)_1.5rem] " +
"[inline-size:calc(100%_*_var(--candle-scale))] [min-inline-size:100%] " +
"[min-block-size:100%] [direction:ltr]",
},
viewport: {
className:
"relative [grid-column:1] [grid-row:1] [min-inline-size:0] [min-block-size:18rem] " +
"overflow-clip [overscroll-behavior:none] " +
"[&:has(>[data-uiify-virtual-scroll])]:[background-image:linear-gradient(to_right,_var(--candle-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--candle-grid)_1px,_transparent_1px)] " +
"[&:has(>[data-uiify-virtual-scroll])]:[background-size:10%_100%,_100%_25%]",
},
candles: {
className:
"absolute [inset-block:0] [inset-inline:auto_0] [inline-size:100%] m-0 " +
"[padding:1rem_0.5rem] list-none " +
"[background-image:linear-gradient(to_right,_var(--candle-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--candle-grid)_1px,_transparent_1px)] " +
"[background-size:10%_100%,_100%_25%]",
},
timeViewport: {
className:
"relative [grid-column:1] [grid-row:2] [min-inline-size:0] overflow-clip " + "[overscroll-behavior:none]",
},
timeAxis: {
className:
"relative [inset-block:0] [inline-size:var(--candle-content-size,_100%)] " +
"[translate:calc(-1_*_var(--candle-scroll-x,_0px))_0] [min-inline-size:0] m-0 p-0 " +
"list-none",
},
priceAxis: { className: "relative [grid-column:2] [grid-row:1] [min-inline-size:0] m-0 p-0 list-none" },
dataTable: {
className:
"absolute [inline-size:1px] [block-size:1px] overflow-hidden " + "[clip-path:inset(50%)] whitespace-nowrap",
},
};
export default function Example() {
return (
<>
<CandleChart
className={
"[--candle-grid:color-mix(in_srgb,_currentcolor_10%,_transparent)] [--candle-down:oklch(64%_0.21_24deg)] [" +
"--candle-flat:color-mix(in_srgb,_currentcolor_60%,_transparent)] [--candle-up:oklch(67%_0.14_166deg)] [--" +
"candle-axis:var(--muted-foreground)] relative block [inline-size:100%] [min-block-size:21rem] [padding:1r" +
"em_0.75rem_0.5rem] overflow-clip [overscroll-behavior:none] isolate [color-scheme:light_dark] bg-transpar" +
"ent [color:light-dark(oklch(28%_0.04_165deg),_oklch(82%_0.04_165deg))] data-[interactive]:[touch-action:n" +
"one] [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:absolute [&_[data-part=viewport]>[data-uiify-vi" +
"rtual-scroll]]:inset-0 [&_[data-uiify-virtual-scroll]_[data-part=candle]]:[inset-block:1rem_auto] [&_[dat" +
"a-uiify-virtual-scroll]_[data-part=candle]]:[block-size:calc(var(--candle-plot-height,_18rem)_-_2rem)] [&" +
"_[data-part=candle]]:absolute [&_[data-part=candle]]:[inset:1rem_0.5rem] [&_[data-part=candle]]:pointer-e" +
"vents-none [&_[data-part=candle]]:[inset-inline-start:var(--candle-x)] [&_[data-part=candle]]:[inline-siz" +
"e:var(--candle-slot)] [&_[data-part=candle]]:block [&_[data-part=candle]]:[color:var(--candle-flat)] [&_[" +
"data-part=candle]]:list-none [&[data-interactive]_[data-part=candle]]:[pointer-events:auto] [&_[data-part" +
"=candle-hit]]:absolute [&_[data-part=candle-hit]]:z-[1] [&_[data-part=candle-hit]]:inset-0 [&_[data-part=" +
"candle-hit]]:[inline-size:100%] [&_[data-part=candle-hit]]:[block-size:100%] [&_[data-part=candle-hit]]:m" +
"-0 [&_[data-part=candle-hit]]:p-0 [&_[data-part=candle-hit]]:border-0 [&_[data-part=candle-hit]]:border-c" +
"urrent [&_[data-part=candle-hit]]:border-none [&_[data-part=candle-hit]]:appearance-none [&_[data-part=ca" +
"ndle-hit]]:bg-transparent [&_[data-part=candle-hit]]:text-transparent [&_[data-part=candle-hit]]:[cursor:" +
"crosshair] [&_[data-part=candle-hit]]:[font-style:inherit] [&_[data-part=candle-hit]]:[font-variant:inher" +
"it] [&_[data-part=candle-hit]]:[font-weight:inherit] [&_[data-part=candle-hit]]:[font-stretch:inherit] [&" +
"_[data-part=candle-hit]]:text-[length:inherit] [&_[data-part=candle-hit]]:leading-[inherit] [&_[data-part" +
"=candle-hit]]:font-[family-name:inherit] [&_[data-part=candle]::before]:content-[''] [&_[data-part=candle" +
"]::before]:absolute [&_[data-part=candle]::before]:block [&_[data-part=candle]::before]:[background:curre" +
"ntcolor] [&_[data-part=candle]::after]:content-[''] [&_[data-part=candle]::after]:absolute [&_[data-part=" +
"candle]::after]:block [&_[data-part=candle]::after]:[background:currentcolor] [&_[data-part=candle]::befo" +
"re]:[inset-block-start:var(--candle-wick-top)] [&_[data-part=candle]::before]:[inset-inline-start:50%] [&" +
"_[data-part=candle]::before]:[inline-size:max(1px,_0.08em)] [&_[data-part=candle]::before]:[block-size:va" +
"r(--candle-wick-height)] [&_[data-part=candle]::before]:[transform:translateX(-50%)] [&_[data-part=candle" +
"]::after]:[inset-block-start:var(--candle-body-top)] [&_[data-part=candle]::after]:[inset-inline:17%] [&_" +
"[data-part=candle]::after]:[block-size:var(--candle-body-height)] [&_[data-part=candle]::after]:[min-bloc" +
"k-size:1px] [&_[data-part=candle][data-direction=up]]:[color:var(--candle-up)] [&_[data-part=candle][data" +
"-direction=down]]:[color:var(--candle-down)] [&_[data-part=crosshair]]:absolute [&_[data-part=crosshair]]" +
":z-[3] [&_[data-part=crosshair]]:inset-0 [&_[data-part=crosshair]]:[inline-size:var(--candle-content-size" +
",_100%)] [&_[data-part=crosshair]]:[translate:calc(-1_*_var(--candle-scroll-x,_0px))_0] [&_[data-part=cro" +
"sshair]]:[block-size:100%] [&_[data-part=crosshair]]:[color:light-dark(oklch(52%_0.01_0deg),_oklch(72%_0." +
"01_0deg))] [&_[data-part=crosshair]]:pointer-events-none [&_[data-part=crosshair]::before]:content-[''] [" +
"&_[data-part=crosshair]::before]:absolute [&_[data-part=crosshair]::before]:block [&_[data-part=crosshair" +
"]::before]:[background:currentcolor] [&_[data-part=crosshair]::after]:content-[''] [&_[data-part=crosshai" +
"r]::after]:absolute [&_[data-part=crosshair]::after]:block [&_[data-part=crosshair]::after]:[background:c" +
"urrentcolor] [&_[data-part=crosshair]::before]:[inset-block:0] [&_[data-part=crosshair]::before]:[inset-i" +
"nline-start:var(--candle-crosshair-x)] [&_[data-part=crosshair]::before]:[inline-size:1px] [&_[data-part=" +
"crosshair]::before]:[background-image:repeating-linear-gradient(_to_bottom,_currentcolor_0_0.4rem,_transp" +
"arent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::before]:bg-transparent [&_[data-part=crosshair]::after]:" +
"[inset-block-start:calc(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair]::after]:[inset-inli" +
"ne:0] [&_[data-part=crosshair]::after]:[block-size:1px] [&_[data-part=crosshair]::after]:[background-imag" +
"e:repeating-linear-gradient(_to_right,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=" +
"crosshair]::after]:bg-transparent [&_[data-part=crosshair-marker]]:absolute [&_[data-part=crosshair-marke" +
"r]]:[inset-block-start:calc(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair-marker]]:[inset-" +
"inline-start:var(--candle-crosshair-x)] [&_[data-part=crosshair-marker]]:[font-size:1rem] [&_[data-part=c" +
"rosshair-marker]]:leading-none [&_[data-part=crosshair-marker]]:[transform:translate(-50%,_-50%)] [&_[dat" +
"a-part=time-axis]>[data-part=crosshair-time]]:[inset-block-start:0] [&_[data-part=time-axis]>[data-part=c" +
"rosshair-time]]:[inset-inline-start:var(--candle-crosshair-x)] [&_[data-part=time-axis]>[data-part=crossh" +
"air-time]]:[padding:0.25rem_0.5rem] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[background:var(" +
"--candle-axis)] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[color:Canvas] [&_[data-part=time-ax" +
"is]>[data-part=crosshair-time]]:[font-weight:650] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[t" +
"ransform:translateX(-50%)] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[inset-block-start:calc" +
"(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[inset-inlin" +
"e-end:0] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[padding:0.25rem_0.5rem] [&_[data-part=pr" +
"ice-axis]>[data-part=crosshair-price]]:[background:var(--candle-axis)] [&_[data-part=price-axis]>[data-pa" +
"rt=crosshair-price]]:[color:Canvas] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[font-weight:6" +
"50] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[transform:translateY(-50%)] [&[data-interacti" +
"ve]_[data-part=candle-hit]:focus-visible]:[outline:2px_solid_currentcolor] [&[data-interactive]_[data-par" +
"t=candle-hit]:focus-visible]:[outline-offset:-2px] [&_[data-part=price-axis]>li]:absolute [&_[data-part=p" +
"rice-axis]>li]:[inset-inline:0] [&_[data-part=price-axis]>li]:[inset-block-start:var(--candle-axis-y)] [&" +
"_[data-part=price-axis]>li]:overflow-hidden [&_[data-part=price-axis]>li]:[color:var(--candle-axis)] [&_[" +
"data-part=price-axis]>li]:[font-size:0.65rem] [&_[data-part=price-axis]>li]:[font-variant-numeric:tabular" +
"-nums] [&_[data-part=price-axis]>li]:leading-none [&_[data-part=price-axis]>li]:text-end [&_[data-part=pr" +
"ice-axis]>li]:[text-overflow:ellipsis] [&_[data-part=price-axis]>li]:whitespace-nowrap [&_[data-part=pric" +
"e-axis]>li]:[transform:translateY(-50%)] [&_[data-part=price-axis]>li:first-child]:[transform:none] [&_[d" +
"ata-part=price-axis]>li:last-child]:[transform:translateY(-100%)] [&_[data-part=time-axis]>li]:absolute [" +
"&_[data-part=time-axis]>li]:[inset-block-start:0.375rem] [&_[data-part=time-axis]>li]:[inset-inline-start" +
":var(--candle-axis-x)] [&_[data-part=time-axis]>li]:[color:var(--candle-axis)] [&_[data-part=time-axis]>l" +
"i]:[font-size:0.7rem] [&_[data-part=time-axis]>li]:whitespace-nowrap [&_[data-part=time-axis]>li]:[transf" +
"orm:translateX(-50%)] [&_[data-part=time-axis]>li:first-child]:[transform:none] [&_[data-part=time-axis]>" +
"li:last-child]:[transform:translateX(-100%)] [&_[data-part=time-axis]>li:only-child]:[transform:translate" +
"X(-50%)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[transform:translateX(-50%)] [&_[data-par" +
"t=price-axis]>li[data-part=crosshair-price]]:[transform:translateY(-50%)] group/candle-chart"
}
slotProps={slotProps}
data={data}
aria-label="BTC / USD daily candles"
/>
<CandleChartClient
className={
"[--candle-grid:color-mix(in_srgb,_currentcolor_10%,_transparent)] [--candle-down:oklch(64%_0.21_24deg)] [" +
"--candle-flat:color-mix(in_srgb,_currentcolor_60%,_transparent)] [--candle-up:oklch(67%_0.14_166deg)] [--" +
"candle-axis:var(--muted-foreground)] relative block [inline-size:100%] [min-block-size:21rem] [padding:1r" +
"em_0.75rem_0.5rem] overflow-clip [overscroll-behavior:none] isolate [color-scheme:light_dark] bg-transpar" +
"ent [color:light-dark(oklch(28%_0.04_165deg),_oklch(82%_0.04_165deg))] data-[interactive]:[touch-action:n" +
"one] [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:absolute [&_[data-part=viewport]>[data-uiify-vi" +
"rtual-scroll]]:inset-0 [&_[data-uiify-virtual-scroll]_[data-part=candle]]:[inset-block:1rem_auto] [&_[dat" +
"a-uiify-virtual-scroll]_[data-part=candle]]:[block-size:calc(var(--candle-plot-height,_18rem)_-_2rem)] [&" +
"_[data-part=candle]]:absolute [&_[data-part=candle]]:[inset:1rem_0.5rem] [&_[data-part=candle]]:pointer-e" +
"vents-none [&_[data-part=candle]]:[inset-inline-start:var(--candle-x)] [&_[data-part=candle]]:[inline-siz" +
"e:var(--candle-slot)] [&_[data-part=candle]]:block [&_[data-part=candle]]:[color:var(--candle-flat)] [&_[" +
"data-part=candle]]:list-none [&[data-interactive]_[data-part=candle]]:[pointer-events:auto] [&_[data-part" +
"=candle-hit]]:absolute [&_[data-part=candle-hit]]:z-[1] [&_[data-part=candle-hit]]:inset-0 [&_[data-part=" +
"candle-hit]]:[inline-size:100%] [&_[data-part=candle-hit]]:[block-size:100%] [&_[data-part=candle-hit]]:m" +
"-0 [&_[data-part=candle-hit]]:p-0 [&_[data-part=candle-hit]]:border-0 [&_[data-part=candle-hit]]:border-c" +
"urrent [&_[data-part=candle-hit]]:border-none [&_[data-part=candle-hit]]:appearance-none [&_[data-part=ca" +
"ndle-hit]]:bg-transparent [&_[data-part=candle-hit]]:text-transparent [&_[data-part=candle-hit]]:[cursor:" +
"crosshair] [&_[data-part=candle-hit]]:[font-style:inherit] [&_[data-part=candle-hit]]:[font-variant:inher" +
"it] [&_[data-part=candle-hit]]:[font-weight:inherit] [&_[data-part=candle-hit]]:[font-stretch:inherit] [&" +
"_[data-part=candle-hit]]:text-[length:inherit] [&_[data-part=candle-hit]]:leading-[inherit] [&_[data-part" +
"=candle-hit]]:font-[family-name:inherit] [&_[data-part=candle]::before]:content-[''] [&_[data-part=candle" +
"]::before]:absolute [&_[data-part=candle]::before]:block [&_[data-part=candle]::before]:[background:curre" +
"ntcolor] [&_[data-part=candle]::after]:content-[''] [&_[data-part=candle]::after]:absolute [&_[data-part=" +
"candle]::after]:block [&_[data-part=candle]::after]:[background:currentcolor] [&_[data-part=candle]::befo" +
"re]:[inset-block-start:var(--candle-wick-top)] [&_[data-part=candle]::before]:[inset-inline-start:50%] [&" +
"_[data-part=candle]::before]:[inline-size:max(1px,_0.08em)] [&_[data-part=candle]::before]:[block-size:va" +
"r(--candle-wick-height)] [&_[data-part=candle]::before]:[transform:translateX(-50%)] [&_[data-part=candle" +
"]::after]:[inset-block-start:var(--candle-body-top)] [&_[data-part=candle]::after]:[inset-inline:17%] [&_" +
"[data-part=candle]::after]:[block-size:var(--candle-body-height)] [&_[data-part=candle]::after]:[min-bloc" +
"k-size:1px] [&_[data-part=candle][data-direction=up]]:[color:var(--candle-up)] [&_[data-part=candle][data" +
"-direction=down]]:[color:var(--candle-down)] [&_[data-part=crosshair]]:absolute [&_[data-part=crosshair]]" +
":z-[3] [&_[data-part=crosshair]]:inset-0 [&_[data-part=crosshair]]:[inline-size:var(--candle-content-size" +
",_100%)] [&_[data-part=crosshair]]:[translate:calc(-1_*_var(--candle-scroll-x,_0px))_0] [&_[data-part=cro" +
"sshair]]:[block-size:100%] [&_[data-part=crosshair]]:[color:light-dark(oklch(52%_0.01_0deg),_oklch(72%_0." +
"01_0deg))] [&_[data-part=crosshair]]:pointer-events-none [&_[data-part=crosshair]::before]:content-[''] [" +
"&_[data-part=crosshair]::before]:absolute [&_[data-part=crosshair]::before]:block [&_[data-part=crosshair" +
"]::before]:[background:currentcolor] [&_[data-part=crosshair]::after]:content-[''] [&_[data-part=crosshai" +
"r]::after]:absolute [&_[data-part=crosshair]::after]:block [&_[data-part=crosshair]::after]:[background:c" +
"urrentcolor] [&_[data-part=crosshair]::before]:[inset-block:0] [&_[data-part=crosshair]::before]:[inset-i" +
"nline-start:var(--candle-crosshair-x)] [&_[data-part=crosshair]::before]:[inline-size:1px] [&_[data-part=" +
"crosshair]::before]:[background-image:repeating-linear-gradient(_to_bottom,_currentcolor_0_0.4rem,_transp" +
"arent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::before]:bg-transparent [&_[data-part=crosshair]::after]:" +
"[inset-block-start:calc(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair]::after]:[inset-inli" +
"ne:0] [&_[data-part=crosshair]::after]:[block-size:1px] [&_[data-part=crosshair]::after]:[background-imag" +
"e:repeating-linear-gradient(_to_right,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=" +
"crosshair]::after]:bg-transparent [&_[data-part=crosshair-marker]]:absolute [&_[data-part=crosshair-marke" +
"r]]:[inset-block-start:calc(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair-marker]]:[inset-" +
"inline-start:var(--candle-crosshair-x)] [&_[data-part=crosshair-marker]]:[font-size:1rem] [&_[data-part=c" +
"rosshair-marker]]:leading-none [&_[data-part=crosshair-marker]]:[transform:translate(-50%,_-50%)] [&_[dat" +
"a-part=time-axis]>[data-part=crosshair-time]]:[inset-block-start:0] [&_[data-part=time-axis]>[data-part=c" +
"rosshair-time]]:[inset-inline-start:var(--candle-crosshair-x)] [&_[data-part=time-axis]>[data-part=crossh" +
"air-time]]:[padding:0.25rem_0.5rem] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[background:var(" +
"--candle-axis)] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[color:Canvas] [&_[data-part=time-ax" +
"is]>[data-part=crosshair-time]]:[font-weight:650] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[t" +
"ransform:translateX(-50%)] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[inset-block-start:calc" +
"(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[inset-inlin" +
"e-end:0] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[padding:0.25rem_0.5rem] [&_[data-part=pr" +
"ice-axis]>[data-part=crosshair-price]]:[background:var(--candle-axis)] [&_[data-part=price-axis]>[data-pa" +
"rt=crosshair-price]]:[color:Canvas] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[font-weight:6" +
"50] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[transform:translateY(-50%)] [&[data-interacti" +
"ve]_[data-part=candle-hit]:focus-visible]:[outline:2px_solid_currentcolor] [&[data-interactive]_[data-par" +
"t=candle-hit]:focus-visible]:[outline-offset:-2px] [&_[data-part=price-axis]>li]:absolute [&_[data-part=p" +
"rice-axis]>li]:[inset-inline:0] [&_[data-part=price-axis]>li]:[inset-block-start:var(--candle-axis-y)] [&" +
"_[data-part=price-axis]>li]:overflow-hidden [&_[data-part=price-axis]>li]:[color:var(--candle-axis)] [&_[" +
"data-part=price-axis]>li]:[font-size:0.65rem] [&_[data-part=price-axis]>li]:[font-variant-numeric:tabular" +
"-nums] [&_[data-part=price-axis]>li]:leading-none [&_[data-part=price-axis]>li]:text-end [&_[data-part=pr" +
"ice-axis]>li]:[text-overflow:ellipsis] [&_[data-part=price-axis]>li]:whitespace-nowrap [&_[data-part=pric" +
"e-axis]>li]:[transform:translateY(-50%)] [&_[data-part=price-axis]>li:first-child]:[transform:none] [&_[d" +
"ata-part=price-axis]>li:last-child]:[transform:translateY(-100%)] [&_[data-part=time-axis]>li]:absolute [" +
"&_[data-part=time-axis]>li]:[inset-block-start:0.375rem] [&_[data-part=time-axis]>li]:[inset-inline-start" +
":var(--candle-axis-x)] [&_[data-part=time-axis]>li]:[color:var(--candle-axis)] [&_[data-part=time-axis]>l" +
"i]:[font-size:0.7rem] [&_[data-part=time-axis]>li]:whitespace-nowrap [&_[data-part=time-axis]>li]:[transf" +
"orm:translateX(-50%)] [&_[data-part=time-axis]>li:first-child]:[transform:none] [&_[data-part=time-axis]>" +
"li:last-child]:[transform:translateX(-100%)] [&_[data-part=time-axis]>li:only-child]:[transform:translate" +
"X(-50%)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[transform:translateX(-50%)] [&_[data-par" +
"t=price-axis]>li[data-part=crosshair-price]]:[transform:translateY(-50%)] group/candle-chart"
}
slotProps={slotProps}
data={data}
aria-label="Interactive BTC / USD daily candles"
/>
<LiveChart />
</>
);
}
function LiveChart() {
const [candles, setCandles] = useState(data);
const [running, setRunning] = useState(false);
useEffect(() => {
if (!running) return;
const timer = setInterval(() => {
setCandles((current) => {
const last = current.at(-1);
if (!last) return current;
const close = Math.round(last.close * (1 + (Math.random() - 0.5) * 0.004));
const next = {
time: String(current.length),
open: last.close,
high: Math.max(last.close, close),
low: Math.min(last.close, close),
close,
};
return [...current, next];
});
}, 1000);
return () => clearInterval(timer);
}, [running]);
return (
<>
<button type="button" onClick={() => setRunning((value) => !value)}>
{running ? "Stop" : "Start"}
</button>
{/* All candles, virtualized; 20 fit the viewport and new ones stay in view at the end. */}
<CandleChartClient
className={
"[--candle-grid:color-mix(in_srgb,_currentcolor_10%,_transparent)] [--candle-down:oklch(64%_0.21_24deg)] [" +
"--candle-flat:color-mix(in_srgb,_currentcolor_60%,_transparent)] [--candle-up:oklch(67%_0.14_166deg)] [--" +
"candle-axis:var(--muted-foreground)] relative block [inline-size:100%] [min-block-size:21rem] [padding:1r" +
"em_0.75rem_0.5rem] overflow-clip [overscroll-behavior:none] isolate [color-scheme:light_dark] bg-transpar" +
"ent [color:light-dark(oklch(28%_0.04_165deg),_oklch(82%_0.04_165deg))] data-[interactive]:[touch-action:n" +
"one] [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:absolute [&_[data-part=viewport]>[data-uiify-vi" +
"rtual-scroll]]:inset-0 [&_[data-uiify-virtual-scroll]_[data-part=candle]]:[inset-block:1rem_auto] [&_[dat" +
"a-uiify-virtual-scroll]_[data-part=candle]]:[block-size:calc(var(--candle-plot-height,_18rem)_-_2rem)] [&" +
"_[data-part=candle]]:absolute [&_[data-part=candle]]:[inset:1rem_0.5rem] [&_[data-part=candle]]:pointer-e" +
"vents-none [&_[data-part=candle]]:[inset-inline-start:var(--candle-x)] [&_[data-part=candle]]:[inline-siz" +
"e:var(--candle-slot)] [&_[data-part=candle]]:block [&_[data-part=candle]]:[color:var(--candle-flat)] [&_[" +
"data-part=candle]]:list-none [&[data-interactive]_[data-part=candle]]:[pointer-events:auto] [&_[data-part" +
"=candle-hit]]:absolute [&_[data-part=candle-hit]]:z-[1] [&_[data-part=candle-hit]]:inset-0 [&_[data-part=" +
"candle-hit]]:[inline-size:100%] [&_[data-part=candle-hit]]:[block-size:100%] [&_[data-part=candle-hit]]:m" +
"-0 [&_[data-part=candle-hit]]:p-0 [&_[data-part=candle-hit]]:border-0 [&_[data-part=candle-hit]]:border-c" +
"urrent [&_[data-part=candle-hit]]:border-none [&_[data-part=candle-hit]]:appearance-none [&_[data-part=ca" +
"ndle-hit]]:bg-transparent [&_[data-part=candle-hit]]:text-transparent [&_[data-part=candle-hit]]:[cursor:" +
"crosshair] [&_[data-part=candle-hit]]:[font-style:inherit] [&_[data-part=candle-hit]]:[font-variant:inher" +
"it] [&_[data-part=candle-hit]]:[font-weight:inherit] [&_[data-part=candle-hit]]:[font-stretch:inherit] [&" +
"_[data-part=candle-hit]]:text-[length:inherit] [&_[data-part=candle-hit]]:leading-[inherit] [&_[data-part" +
"=candle-hit]]:font-[family-name:inherit] [&_[data-part=candle]::before]:content-[''] [&_[data-part=candle" +
"]::before]:absolute [&_[data-part=candle]::before]:block [&_[data-part=candle]::before]:[background:curre" +
"ntcolor] [&_[data-part=candle]::after]:content-[''] [&_[data-part=candle]::after]:absolute [&_[data-part=" +
"candle]::after]:block [&_[data-part=candle]::after]:[background:currentcolor] [&_[data-part=candle]::befo" +
"re]:[inset-block-start:var(--candle-wick-top)] [&_[data-part=candle]::before]:[inset-inline-start:50%] [&" +
"_[data-part=candle]::before]:[inline-size:max(1px,_0.08em)] [&_[data-part=candle]::before]:[block-size:va" +
"r(--candle-wick-height)] [&_[data-part=candle]::before]:[transform:translateX(-50%)] [&_[data-part=candle" +
"]::after]:[inset-block-start:var(--candle-body-top)] [&_[data-part=candle]::after]:[inset-inline:17%] [&_" +
"[data-part=candle]::after]:[block-size:var(--candle-body-height)] [&_[data-part=candle]::after]:[min-bloc" +
"k-size:1px] [&_[data-part=candle][data-direction=up]]:[color:var(--candle-up)] [&_[data-part=candle][data" +
"-direction=down]]:[color:var(--candle-down)] [&_[data-part=crosshair]]:absolute [&_[data-part=crosshair]]" +
":z-[3] [&_[data-part=crosshair]]:inset-0 [&_[data-part=crosshair]]:[inline-size:var(--candle-content-size" +
",_100%)] [&_[data-part=crosshair]]:[translate:calc(-1_*_var(--candle-scroll-x,_0px))_0] [&_[data-part=cro" +
"sshair]]:[block-size:100%] [&_[data-part=crosshair]]:[color:light-dark(oklch(52%_0.01_0deg),_oklch(72%_0." +
"01_0deg))] [&_[data-part=crosshair]]:pointer-events-none [&_[data-part=crosshair]::before]:content-[''] [" +
"&_[data-part=crosshair]::before]:absolute [&_[data-part=crosshair]::before]:block [&_[data-part=crosshair" +
"]::before]:[background:currentcolor] [&_[data-part=crosshair]::after]:content-[''] [&_[data-part=crosshai" +
"r]::after]:absolute [&_[data-part=crosshair]::after]:block [&_[data-part=crosshair]::after]:[background:c" +
"urrentcolor] [&_[data-part=crosshair]::before]:[inset-block:0] [&_[data-part=crosshair]::before]:[inset-i" +
"nline-start:var(--candle-crosshair-x)] [&_[data-part=crosshair]::before]:[inline-size:1px] [&_[data-part=" +
"crosshair]::before]:[background-image:repeating-linear-gradient(_to_bottom,_currentcolor_0_0.4rem,_transp" +
"arent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::before]:bg-transparent [&_[data-part=crosshair]::after]:" +
"[inset-block-start:calc(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair]::after]:[inset-inli" +
"ne:0] [&_[data-part=crosshair]::after]:[block-size:1px] [&_[data-part=crosshair]::after]:[background-imag" +
"e:repeating-linear-gradient(_to_right,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=" +
"crosshair]::after]:bg-transparent [&_[data-part=crosshair-marker]]:absolute [&_[data-part=crosshair-marke" +
"r]]:[inset-block-start:calc(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair-marker]]:[inset-" +
"inline-start:var(--candle-crosshair-x)] [&_[data-part=crosshair-marker]]:[font-size:1rem] [&_[data-part=c" +
"rosshair-marker]]:leading-none [&_[data-part=crosshair-marker]]:[transform:translate(-50%,_-50%)] [&_[dat" +
"a-part=time-axis]>[data-part=crosshair-time]]:[inset-block-start:0] [&_[data-part=time-axis]>[data-part=c" +
"rosshair-time]]:[inset-inline-start:var(--candle-crosshair-x)] [&_[data-part=time-axis]>[data-part=crossh" +
"air-time]]:[padding:0.25rem_0.5rem] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[background:var(" +
"--candle-axis)] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[color:Canvas] [&_[data-part=time-ax" +
"is]>[data-part=crosshair-time]]:[font-weight:650] [&_[data-part=time-axis]>[data-part=crosshair-time]]:[t" +
"ransform:translateX(-50%)] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[inset-block-start:calc" +
"(var(--candle-cursor-y,_50%)_+_1rem)] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[inset-inlin" +
"e-end:0] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[padding:0.25rem_0.5rem] [&_[data-part=pr" +
"ice-axis]>[data-part=crosshair-price]]:[background:var(--candle-axis)] [&_[data-part=price-axis]>[data-pa" +
"rt=crosshair-price]]:[color:Canvas] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[font-weight:6" +
"50] [&_[data-part=price-axis]>[data-part=crosshair-price]]:[transform:translateY(-50%)] [&[data-interacti" +
"ve]_[data-part=candle-hit]:focus-visible]:[outline:2px_solid_currentcolor] [&[data-interactive]_[data-par" +
"t=candle-hit]:focus-visible]:[outline-offset:-2px] [&_[data-part=price-axis]>li]:absolute [&_[data-part=p" +
"rice-axis]>li]:[inset-inline:0] [&_[data-part=price-axis]>li]:[inset-block-start:var(--candle-axis-y)] [&" +
"_[data-part=price-axis]>li]:overflow-hidden [&_[data-part=price-axis]>li]:[color:var(--candle-axis)] [&_[" +
"data-part=price-axis]>li]:[font-size:0.65rem] [&_[data-part=price-axis]>li]:[font-variant-numeric:tabular" +
"-nums] [&_[data-part=price-axis]>li]:leading-none [&_[data-part=price-axis]>li]:text-end [&_[data-part=pr" +
"ice-axis]>li]:[text-overflow:ellipsis] [&_[data-part=price-axis]>li]:whitespace-nowrap [&_[data-part=pric" +
"e-axis]>li]:[transform:translateY(-50%)] [&_[data-part=price-axis]>li:first-child]:[transform:none] [&_[d" +
"ata-part=price-axis]>li:last-child]:[transform:translateY(-100%)] [&_[data-part=time-axis]>li]:absolute [" +
"&_[data-part=time-axis]>li]:[inset-block-start:0.375rem] [&_[data-part=time-axis]>li]:[inset-inline-start" +
":var(--candle-axis-x)] [&_[data-part=time-axis]>li]:[color:var(--candle-axis)] [&_[data-part=time-axis]>l" +
"i]:[font-size:0.7rem] [&_[data-part=time-axis]>li]:whitespace-nowrap [&_[data-part=time-axis]>li]:[transf" +
"orm:translateX(-50%)] [&_[data-part=time-axis]>li:first-child]:[transform:none] [&_[data-part=time-axis]>" +
"li:last-child]:[transform:translateX(-100%)] [&_[data-part=time-axis]>li:only-child]:[transform:translate" +
"X(-50%)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[transform:translateX(-50%)] [&_[data-par" +
"t=price-axis]>li[data-part=crosshair-price]]:[transform:translateY(-50%)] group/candle-chart"
}
slotProps={slotProps}
data={candles}
visibleCount={20}
aria-label="Live BTC / USD candles"
/>
</>
);
}