@shipfox/react-ui 0.16.0 → 0.18.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.
Files changed (51) hide show
  1. package/dist/components/card/card.d.ts +24 -0
  2. package/dist/components/card/card.js +56 -0
  3. package/dist/components/card/card.stories.js +216 -0
  4. package/dist/components/card/index.d.ts +2 -0
  5. package/dist/components/card/index.js +3 -0
  6. package/dist/components/count-up/count-up.d.ts +14 -0
  7. package/dist/components/count-up/count-up.js +98 -0
  8. package/dist/components/count-up/count-up.stories.js +568 -0
  9. package/dist/components/count-up/index.d.ts +2 -0
  10. package/dist/components/count-up/index.js +3 -0
  11. package/dist/components/dashboard/components/charts/bar-chart.d.ts +8 -17
  12. package/dist/components/dashboard/components/charts/bar-chart.js +127 -81
  13. package/dist/components/dashboard/components/charts/bar-chart.stories.js +287 -0
  14. package/dist/components/dashboard/components/charts/chart-tooltip.js +13 -12
  15. package/dist/components/dashboard/components/charts/colors.d.ts +3 -2
  16. package/dist/components/dashboard/components/charts/colors.js +5 -2
  17. package/dist/components/dashboard/components/charts/index.d.ts +1 -0
  18. package/dist/components/dashboard/components/charts/index.js +1 -0
  19. package/dist/components/dashboard/components/charts/line-chart.d.ts +7 -16
  20. package/dist/components/dashboard/components/charts/line-chart.js +132 -108
  21. package/dist/components/dashboard/components/charts/line-chart.stories.js +257 -0
  22. package/dist/components/dashboard/components/charts/utils.d.ts +13 -0
  23. package/dist/components/dashboard/components/charts/utils.js +18 -0
  24. package/dist/components/dashboard/components/kpi-card.d.ts +8 -9
  25. package/dist/components/dashboard/components/kpi-card.js +26 -44
  26. package/dist/components/dashboard/index.d.ts +2 -7
  27. package/dist/components/dashboard/index.js +0 -11
  28. package/dist/components/dashboard/pages/analytics-page.d.ts +0 -18
  29. package/dist/components/dashboard/pages/analytics-page.js +83 -37
  30. package/dist/components/dashboard/pages/jobs-page.d.ts +0 -18
  31. package/dist/components/dashboard/pages/jobs-page.js +27 -24
  32. package/dist/components/dashboard/table/table-wrapper.d.ts +21 -24
  33. package/dist/components/dashboard/table/table-wrapper.js +38 -51
  34. package/dist/components/empty-state/empty-state.d.ts +10 -0
  35. package/dist/components/empty-state/empty-state.js +40 -0
  36. package/dist/components/empty-state/empty-state.stories.js +74 -0
  37. package/dist/components/empty-state/index.d.ts +2 -0
  38. package/dist/components/empty-state/index.js +3 -0
  39. package/dist/components/index.d.ts +4 -0
  40. package/dist/components/index.js +4 -0
  41. package/dist/components/item/item.stories.js +3 -3
  42. package/dist/components/table/data-table.d.ts +12 -1
  43. package/dist/components/table/data-table.js +84 -71
  44. package/dist/components/table/table-column-header.d.ts +14 -1
  45. package/dist/components/table/table-column-header.js +12 -5
  46. package/dist/components/table/table-pagination.d.ts +14 -1
  47. package/dist/components/table/table-pagination.js +6 -2
  48. package/dist/components/table/table.js +3 -3
  49. package/dist/components/table/table.stories.components.js +6 -28
  50. package/dist/styles.css +1 -1
  51. package/package.json +3 -3
@@ -0,0 +1,568 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Code } from '../../components/typography/index.js';
3
+ import { useInView, useMotionValue, useSpring } from 'framer-motion';
4
+ import { useCallback, useEffect, useRef, useState } from 'react';
5
+ import { formatNumberCompact } from '../../utils/format/number.js';
6
+ import { CountUp } from './count-up.js';
7
+ const meta = {
8
+ title: 'Components/CountUp',
9
+ component: CountUp,
10
+ tags: [
11
+ 'autodocs'
12
+ ],
13
+ parameters: {
14
+ layout: 'centered'
15
+ },
16
+ argTypes: {
17
+ to: {
18
+ control: 'number'
19
+ },
20
+ from: {
21
+ control: 'number'
22
+ },
23
+ direction: {
24
+ control: 'select',
25
+ options: [
26
+ 'up',
27
+ 'down'
28
+ ]
29
+ },
30
+ delay: {
31
+ control: 'number'
32
+ },
33
+ duration: {
34
+ control: 'number'
35
+ },
36
+ separator: {
37
+ control: 'text'
38
+ },
39
+ startWhen: {
40
+ control: 'boolean'
41
+ }
42
+ },
43
+ args: {
44
+ to: 1000,
45
+ from: 0,
46
+ direction: 'up',
47
+ delay: 0,
48
+ duration: 2,
49
+ separator: '',
50
+ startWhen: true
51
+ }
52
+ };
53
+ export default meta;
54
+ export const Default = {
55
+ args: {
56
+ to: 1000,
57
+ from: 0
58
+ }
59
+ };
60
+ export const Basic = {
61
+ render: ()=>/*#__PURE__*/ _jsxs("div", {
62
+ className: "flex flex-col gap-32",
63
+ children: [
64
+ /*#__PURE__*/ _jsxs("div", {
65
+ className: "flex flex-col gap-8",
66
+ children: [
67
+ /*#__PURE__*/ _jsx(Code, {
68
+ variant: "label",
69
+ className: "text-foreground-neutral-subtle",
70
+ children: "Count from 0 to 1000"
71
+ }),
72
+ /*#__PURE__*/ _jsx("div", {
73
+ className: "text-4xl font-semibold",
74
+ children: /*#__PURE__*/ _jsx(CountUp, {
75
+ to: 1000,
76
+ from: 0,
77
+ duration: 2
78
+ })
79
+ })
80
+ ]
81
+ }),
82
+ /*#__PURE__*/ _jsxs("div", {
83
+ className: "flex flex-col gap-8",
84
+ children: [
85
+ /*#__PURE__*/ _jsx(Code, {
86
+ variant: "label",
87
+ className: "text-foreground-neutral-subtle",
88
+ children: "Count from 500 to 1000"
89
+ }),
90
+ /*#__PURE__*/ _jsx("div", {
91
+ className: "text-4xl font-semibold",
92
+ children: /*#__PURE__*/ _jsx(CountUp, {
93
+ to: 1000,
94
+ from: 500,
95
+ duration: 2
96
+ })
97
+ })
98
+ ]
99
+ }),
100
+ /*#__PURE__*/ _jsxs("div", {
101
+ className: "flex flex-col gap-8",
102
+ children: [
103
+ /*#__PURE__*/ _jsx(Code, {
104
+ variant: "label",
105
+ className: "text-foreground-neutral-subtle",
106
+ children: "Count down from 1000 to 0"
107
+ }),
108
+ /*#__PURE__*/ _jsx("div", {
109
+ className: "text-4xl font-semibold",
110
+ children: /*#__PURE__*/ _jsx(CountUp, {
111
+ to: 1000,
112
+ from: 0,
113
+ direction: "down",
114
+ duration: 2
115
+ })
116
+ })
117
+ ]
118
+ })
119
+ ]
120
+ })
121
+ };
122
+ export const WithSeparator = {
123
+ render: ()=>/*#__PURE__*/ _jsxs("div", {
124
+ className: "flex flex-col gap-32",
125
+ children: [
126
+ /*#__PURE__*/ _jsxs("div", {
127
+ className: "flex flex-col gap-8",
128
+ children: [
129
+ /*#__PURE__*/ _jsx(Code, {
130
+ variant: "label",
131
+ className: "text-foreground-neutral-subtle",
132
+ children: "With comma separator"
133
+ }),
134
+ /*#__PURE__*/ _jsx("div", {
135
+ className: "text-4xl font-semibold",
136
+ children: /*#__PURE__*/ _jsx(CountUp, {
137
+ to: 1234567,
138
+ from: 0,
139
+ duration: 2,
140
+ separator: ","
141
+ })
142
+ })
143
+ ]
144
+ }),
145
+ /*#__PURE__*/ _jsxs("div", {
146
+ className: "flex flex-col gap-8",
147
+ children: [
148
+ /*#__PURE__*/ _jsx(Code, {
149
+ variant: "label",
150
+ className: "text-foreground-neutral-subtle",
151
+ children: "With space separator"
152
+ }),
153
+ /*#__PURE__*/ _jsx("div", {
154
+ className: "text-4xl font-semibold",
155
+ children: /*#__PURE__*/ _jsx(CountUp, {
156
+ to: 1234567,
157
+ from: 0,
158
+ duration: 2,
159
+ separator: " "
160
+ })
161
+ })
162
+ ]
163
+ })
164
+ ]
165
+ })
166
+ };
167
+ export const WithDecimals = {
168
+ render: ()=>/*#__PURE__*/ _jsxs("div", {
169
+ className: "flex flex-col gap-32",
170
+ children: [
171
+ /*#__PURE__*/ _jsxs("div", {
172
+ className: "flex flex-col gap-8",
173
+ children: [
174
+ /*#__PURE__*/ _jsx(Code, {
175
+ variant: "label",
176
+ className: "text-foreground-neutral-subtle",
177
+ children: "With 1 decimal place"
178
+ }),
179
+ /*#__PURE__*/ _jsx("div", {
180
+ className: "text-4xl font-semibold",
181
+ children: /*#__PURE__*/ _jsx(CountUp, {
182
+ to: 99.5,
183
+ from: 0,
184
+ duration: 2
185
+ })
186
+ })
187
+ ]
188
+ }),
189
+ /*#__PURE__*/ _jsxs("div", {
190
+ className: "flex flex-col gap-8",
191
+ children: [
192
+ /*#__PURE__*/ _jsx(Code, {
193
+ variant: "label",
194
+ className: "text-foreground-neutral-subtle",
195
+ children: "With 2 decimal places"
196
+ }),
197
+ /*#__PURE__*/ _jsx("div", {
198
+ className: "text-4xl font-semibold",
199
+ children: /*#__PURE__*/ _jsx(CountUp, {
200
+ to: 123.45,
201
+ from: 0,
202
+ duration: 2
203
+ })
204
+ })
205
+ ]
206
+ })
207
+ ]
208
+ })
209
+ };
210
+ export const WithDelay = {
211
+ render: ()=>/*#__PURE__*/ _jsxs("div", {
212
+ className: "flex flex-col gap-32",
213
+ children: [
214
+ /*#__PURE__*/ _jsxs("div", {
215
+ className: "flex flex-col gap-8",
216
+ children: [
217
+ /*#__PURE__*/ _jsx(Code, {
218
+ variant: "label",
219
+ className: "text-foreground-neutral-subtle",
220
+ children: "With 1 second delay"
221
+ }),
222
+ /*#__PURE__*/ _jsx("div", {
223
+ className: "text-4xl font-semibold",
224
+ children: /*#__PURE__*/ _jsx(CountUp, {
225
+ to: 1000,
226
+ from: 0,
227
+ duration: 2,
228
+ delay: 1
229
+ })
230
+ })
231
+ ]
232
+ }),
233
+ /*#__PURE__*/ _jsxs("div", {
234
+ className: "flex flex-col gap-8",
235
+ children: [
236
+ /*#__PURE__*/ _jsx(Code, {
237
+ variant: "label",
238
+ className: "text-foreground-neutral-subtle",
239
+ children: "With 2 second delay"
240
+ }),
241
+ /*#__PURE__*/ _jsx("div", {
242
+ className: "text-4xl font-semibold",
243
+ children: /*#__PURE__*/ _jsx(CountUp, {
244
+ to: 1000,
245
+ from: 0,
246
+ duration: 2,
247
+ delay: 2
248
+ })
249
+ })
250
+ ]
251
+ })
252
+ ]
253
+ })
254
+ };
255
+ export const DifferentDurations = {
256
+ render: ()=>/*#__PURE__*/ _jsxs("div", {
257
+ className: "flex flex-col gap-32",
258
+ children: [
259
+ /*#__PURE__*/ _jsxs("div", {
260
+ className: "flex flex-col gap-8",
261
+ children: [
262
+ /*#__PURE__*/ _jsx(Code, {
263
+ variant: "label",
264
+ className: "text-foreground-neutral-subtle",
265
+ children: "Fast (0.5s)"
266
+ }),
267
+ /*#__PURE__*/ _jsx("div", {
268
+ className: "text-4xl font-semibold",
269
+ children: /*#__PURE__*/ _jsx(CountUp, {
270
+ to: 1000,
271
+ from: 0,
272
+ duration: 0.5
273
+ })
274
+ })
275
+ ]
276
+ }),
277
+ /*#__PURE__*/ _jsxs("div", {
278
+ className: "flex flex-col gap-8",
279
+ children: [
280
+ /*#__PURE__*/ _jsx(Code, {
281
+ variant: "label",
282
+ className: "text-foreground-neutral-subtle",
283
+ children: "Normal (2s)"
284
+ }),
285
+ /*#__PURE__*/ _jsx("div", {
286
+ className: "text-4xl font-semibold",
287
+ children: /*#__PURE__*/ _jsx(CountUp, {
288
+ to: 1000,
289
+ from: 0,
290
+ duration: 2
291
+ })
292
+ })
293
+ ]
294
+ }),
295
+ /*#__PURE__*/ _jsxs("div", {
296
+ className: "flex flex-col gap-8",
297
+ children: [
298
+ /*#__PURE__*/ _jsx(Code, {
299
+ variant: "label",
300
+ className: "text-foreground-neutral-subtle",
301
+ children: "Slow (5s)"
302
+ }),
303
+ /*#__PURE__*/ _jsx("div", {
304
+ className: "text-4xl font-semibold",
305
+ children: /*#__PURE__*/ _jsx(CountUp, {
306
+ to: 1000,
307
+ from: 0,
308
+ duration: 5
309
+ })
310
+ })
311
+ ]
312
+ })
313
+ ]
314
+ })
315
+ };
316
+ export const WithCallbacks = {
317
+ render: ()=>{
318
+ const [started, setStarted] = useState(false);
319
+ const [ended, setEnded] = useState(false);
320
+ const handleStart = ()=>{
321
+ setStarted(true);
322
+ };
323
+ const handleEnd = ()=>{
324
+ setEnded(true);
325
+ };
326
+ return /*#__PURE__*/ _jsxs("div", {
327
+ className: "flex flex-col gap-16",
328
+ children: [
329
+ /*#__PURE__*/ _jsxs("div", {
330
+ className: "flex flex-col gap-8",
331
+ children: [
332
+ /*#__PURE__*/ _jsx(Code, {
333
+ variant: "label",
334
+ className: "text-foreground-neutral-subtle",
335
+ children: "Callbacks triggered"
336
+ }),
337
+ /*#__PURE__*/ _jsx("div", {
338
+ className: "text-4xl font-semibold",
339
+ children: /*#__PURE__*/ _jsx(CountUp, {
340
+ to: 1000,
341
+ from: 0,
342
+ duration: 2,
343
+ onStart: handleStart,
344
+ onEnd: handleEnd
345
+ })
346
+ })
347
+ ]
348
+ }),
349
+ /*#__PURE__*/ _jsxs("div", {
350
+ className: "flex flex-col gap-4 text-sm",
351
+ children: [
352
+ /*#__PURE__*/ _jsxs("div", {
353
+ children: [
354
+ "Started: ",
355
+ started ? 'Yes' : 'No'
356
+ ]
357
+ }),
358
+ /*#__PURE__*/ _jsxs("div", {
359
+ children: [
360
+ "Ended: ",
361
+ ended ? 'Yes' : 'No'
362
+ ]
363
+ })
364
+ ]
365
+ })
366
+ ]
367
+ });
368
+ }
369
+ };
370
+ function CountUpCompact({ to, from = 0, direction = 'up', delay = 0, duration = 2, className = '', startWhen = true, onStart, onEnd }) {
371
+ const ref = useRef(null);
372
+ const motionValue = useMotionValue(direction === 'down' ? to : from);
373
+ const damping = 20 + 40 * (1 / duration);
374
+ const stiffness = 100 * (1 / duration);
375
+ const springValue = useSpring(motionValue, {
376
+ damping,
377
+ stiffness
378
+ });
379
+ const isInView = useInView(ref, {
380
+ once: true,
381
+ margin: '0px'
382
+ });
383
+ const formatValue = useCallback((latest)=>{
384
+ if (Math.abs(latest) >= 999) {
385
+ return formatNumberCompact(latest);
386
+ }
387
+ const hasDecimals = latest % 1 !== 0;
388
+ const options = {
389
+ useGrouping: false,
390
+ minimumFractionDigits: hasDecimals ? 1 : 0,
391
+ maximumFractionDigits: hasDecimals ? 1 : 0
392
+ };
393
+ return Intl.NumberFormat('en-US', options).format(latest);
394
+ }, []);
395
+ useEffect(()=>{
396
+ if (ref.current) {
397
+ ref.current.textContent = formatValue(direction === 'down' ? to : from);
398
+ }
399
+ }, [
400
+ from,
401
+ to,
402
+ direction,
403
+ formatValue
404
+ ]);
405
+ useEffect(()=>{
406
+ if (isInView && startWhen) {
407
+ if (typeof onStart === 'function') {
408
+ onStart();
409
+ }
410
+ const timeoutId = setTimeout(()=>{
411
+ motionValue.set(direction === 'down' ? from : to);
412
+ }, delay * 1000);
413
+ const durationTimeoutId = setTimeout(()=>{
414
+ if (typeof onEnd === 'function') {
415
+ onEnd();
416
+ }
417
+ }, delay * 1000 + duration * 1000);
418
+ return ()=>{
419
+ clearTimeout(timeoutId);
420
+ clearTimeout(durationTimeoutId);
421
+ };
422
+ }
423
+ }, [
424
+ isInView,
425
+ startWhen,
426
+ motionValue,
427
+ direction,
428
+ from,
429
+ to,
430
+ delay,
431
+ onStart,
432
+ onEnd,
433
+ duration
434
+ ]);
435
+ useEffect(()=>{
436
+ const unsubscribe = springValue.on('change', (latest)=>{
437
+ if (ref.current) {
438
+ ref.current.textContent = formatValue(latest);
439
+ }
440
+ });
441
+ return ()=>unsubscribe();
442
+ }, [
443
+ springValue,
444
+ formatValue
445
+ ]);
446
+ return /*#__PURE__*/ _jsx("span", {
447
+ className: className,
448
+ ref: ref
449
+ });
450
+ }
451
+ export const WithCompactFormat = {
452
+ render: ()=>/*#__PURE__*/ _jsxs("div", {
453
+ className: "flex flex-col gap-32",
454
+ children: [
455
+ /*#__PURE__*/ _jsxs("div", {
456
+ className: "flex flex-col gap-8",
457
+ children: [
458
+ /*#__PURE__*/ _jsx(Code, {
459
+ variant: "label",
460
+ className: "text-foreground-neutral-subtle",
461
+ children: "From 999 to 1.1K"
462
+ }),
463
+ /*#__PURE__*/ _jsx("div", {
464
+ className: "text-4xl font-semibold",
465
+ children: /*#__PURE__*/ _jsx(CountUpCompact, {
466
+ to: 1100,
467
+ from: 999,
468
+ duration: 2
469
+ })
470
+ })
471
+ ]
472
+ }),
473
+ /*#__PURE__*/ _jsxs("div", {
474
+ className: "flex flex-col gap-8",
475
+ children: [
476
+ /*#__PURE__*/ _jsx(Code, {
477
+ variant: "label",
478
+ className: "text-foreground-neutral-subtle",
479
+ children: "From 0 to 1.5K"
480
+ }),
481
+ /*#__PURE__*/ _jsx("div", {
482
+ className: "text-4xl font-semibold",
483
+ children: /*#__PURE__*/ _jsx(CountUpCompact, {
484
+ to: 1500,
485
+ from: 0,
486
+ duration: 2
487
+ })
488
+ })
489
+ ]
490
+ }),
491
+ /*#__PURE__*/ _jsxs("div", {
492
+ className: "flex flex-col gap-8",
493
+ children: [
494
+ /*#__PURE__*/ _jsx(Code, {
495
+ variant: "label",
496
+ className: "text-foreground-neutral-subtle",
497
+ children: "From 999,999 to 1.1M"
498
+ }),
499
+ /*#__PURE__*/ _jsx("div", {
500
+ className: "text-4xl font-semibold",
501
+ children: /*#__PURE__*/ _jsx(CountUpCompact, {
502
+ to: 1100000,
503
+ from: 999999,
504
+ duration: 2
505
+ })
506
+ })
507
+ ]
508
+ }),
509
+ /*#__PURE__*/ _jsxs("div", {
510
+ className: "flex flex-col gap-8",
511
+ children: [
512
+ /*#__PURE__*/ _jsx(Code, {
513
+ variant: "label",
514
+ className: "text-foreground-neutral-subtle",
515
+ children: "From 0 to 2.5M"
516
+ }),
517
+ /*#__PURE__*/ _jsx("div", {
518
+ className: "text-4xl font-semibold",
519
+ children: /*#__PURE__*/ _jsx(CountUpCompact, {
520
+ to: 2500000,
521
+ from: 0,
522
+ duration: 2
523
+ })
524
+ })
525
+ ]
526
+ }),
527
+ /*#__PURE__*/ _jsxs("div", {
528
+ className: "flex flex-col gap-8",
529
+ children: [
530
+ /*#__PURE__*/ _jsx(Code, {
531
+ variant: "label",
532
+ className: "text-foreground-neutral-subtle",
533
+ children: "From 0 to 1.2B"
534
+ }),
535
+ /*#__PURE__*/ _jsx("div", {
536
+ className: "text-4xl font-semibold",
537
+ children: /*#__PURE__*/ _jsx(CountUpCompact, {
538
+ to: 1200000000,
539
+ from: 0,
540
+ duration: 2
541
+ })
542
+ })
543
+ ]
544
+ }),
545
+ /*#__PURE__*/ _jsxs("div", {
546
+ className: "flex flex-col gap-8",
547
+ children: [
548
+ /*#__PURE__*/ _jsx(Code, {
549
+ variant: "label",
550
+ className: "text-foreground-neutral-subtle",
551
+ children: "Count down from 1.5K to 999"
552
+ }),
553
+ /*#__PURE__*/ _jsx("div", {
554
+ className: "text-4xl font-semibold",
555
+ children: /*#__PURE__*/ _jsx(CountUpCompact, {
556
+ to: 999,
557
+ from: 1500,
558
+ direction: "down",
559
+ duration: 2
560
+ })
561
+ })
562
+ ]
563
+ })
564
+ ]
565
+ })
566
+ };
567
+
568
+ //# sourceMappingURL=count-up.stories.js.map
@@ -0,0 +1,2 @@
1
+ export * from './count-up';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from './count-up.js';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -1,34 +1,25 @@
1
1
  import type { ComponentProps } from 'react';
2
- import { type BarProps, BarChart as RechartsBarChart } from 'recharts';
3
- import { type ChartColor } from './colors';
2
+ import { type BarProps, type CartesianGridProps, BarChart as RechartsBarChart, type XAxisProps, type YAxisProps } from 'recharts';
3
+ import type { ChartColor } from './colors';
4
4
  export type RechartsBarChartProps = ComponentProps<typeof RechartsBarChart>;
5
5
  export interface BarChartBar extends Omit<BarProps, 'dataKey'> {
6
6
  dataKey: string;
7
7
  name?: string;
8
8
  color?: ChartColor;
9
+ hide?: boolean;
10
+ stackId?: string;
9
11
  }
10
12
  export interface BarChartProps {
11
13
  data: RechartsBarChartProps['data'];
12
14
  bars: BarChartBar[];
13
15
  syncId?: RechartsBarChartProps['syncId'];
14
16
  height?: number;
15
- xAxis?: {
16
- dataKey?: string;
17
- tickFormatter?: (value: string) => string;
18
- hide?: boolean;
19
- interval?: number | 'preserveStart' | 'preserveEnd' | 'preserveStartEnd';
20
- };
21
- yAxis?: {
22
- domain?: [number, number];
23
- ticks?: number[];
24
- hide?: boolean;
25
- };
26
- grid?: {
27
- vertical?: boolean;
28
- horizontal?: boolean;
29
- };
17
+ xAxis?: Pick<XAxisProps, 'dataKey' | 'tickFormatter' | 'hide' | 'interval'>;
18
+ yAxis?: Pick<YAxisProps, 'domain' | 'ticks' | 'hide' | 'tickFormatter'>;
19
+ grid?: Pick<CartesianGridProps, 'vertical' | 'horizontal'>;
30
20
  tooltip?: {
31
21
  labelFormatter?: (label: string) => string;
22
+ formatter?: (value: number) => string;
32
23
  };
33
24
  className?: string;
34
25
  title?: string;