@rinzai/zen 0.14.0 → 0.16.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/CHANGELOG.md +153 -0
- package/README.md +16 -1
- package/dist/animated-number/index.js +14 -14
- package/dist/breadcrumbs/index.js +14 -14
- package/dist/calendar/index.js +29 -29
- package/dist/calendar-heatmap/index.js +12 -12
- package/dist/canvas/index.js +19 -19
- package/dist/carousel/index.d.ts.map +1 -1
- package/dist/carousel/index.js +29 -29
- package/dist/chart/index.js +7 -7
- package/dist/code-block/index.js +5 -5
- package/dist/collapse/index.js +6 -6
- package/dist/color-picker/index.js +10 -10
- package/dist/combobox/index.js +61 -61
- package/dist/command-palette/index.js +5 -5
- package/dist/confirm-dialog/index.js +4 -4
- package/dist/date-picker/index.js +15 -15
- package/dist/dialog/index.d.ts.map +1 -1
- package/dist/dialog/index.js +45 -65
- package/dist/docs/README.md +205 -0
- package/dist/docs/accordion.md +122 -0
- package/dist/docs/alert.md +69 -0
- package/dist/docs/animated-number.md +105 -0
- package/dist/docs/avatar.md +91 -0
- package/dist/docs/backdrop.md +94 -0
- package/dist/docs/badge.md +37 -0
- package/dist/docs/breadcrumbs.md +44 -0
- package/dist/docs/button-group.md +76 -0
- package/dist/docs/button.md +131 -0
- package/dist/docs/calendar-heatmap.md +73 -0
- package/dist/docs/calendar.md +101 -0
- package/dist/docs/canvas.md +584 -0
- package/dist/docs/card.md +180 -0
- package/dist/docs/carousel.md +162 -0
- package/dist/docs/chart.md +325 -0
- package/dist/docs/checkbox.md +88 -0
- package/dist/docs/chip.md +52 -0
- package/dist/docs/code-block.md +116 -0
- package/dist/docs/code-input.md +52 -0
- package/dist/docs/collapse.md +46 -0
- package/dist/docs/color-picker.md +145 -0
- package/dist/docs/combobox.md +208 -0
- package/dist/docs/command-palette.md +65 -0
- package/dist/docs/date-picker.md +167 -0
- package/dist/docs/dialog.md +271 -0
- package/dist/docs/disclosure.md +88 -0
- package/dist/docs/editable-cell.md +90 -0
- package/dist/docs/empty-state.md +46 -0
- package/dist/docs/field.md +82 -0
- package/dist/docs/file-drop.md +44 -0
- package/dist/docs/filter-bar.md +66 -0
- package/dist/docs/header.md +51 -0
- package/dist/docs/hover-card.md +110 -0
- package/dist/docs/icon-picker.md +65 -0
- package/dist/docs/input-group.md +89 -0
- package/dist/docs/input.md +33 -0
- package/dist/docs/inset.md +57 -0
- package/dist/docs/kbd.md +34 -0
- package/dist/docs/keypad.md +51 -0
- package/dist/docs/load-more.md +66 -0
- package/dist/docs/locale-provider.md +99 -0
- package/dist/docs/marquee.md +86 -0
- package/dist/docs/menu.md +456 -0
- package/dist/docs/meter.md +102 -0
- package/dist/docs/money-input.md +169 -0
- package/dist/docs/month-picker.md +80 -0
- package/dist/docs/navigation-menu.md +157 -0
- package/dist/docs/number-field.md +129 -0
- package/dist/docs/page-header.md +44 -0
- package/dist/docs/page-transition.md +93 -0
- package/dist/docs/pagination.md +42 -0
- package/dist/docs/pills.md +85 -0
- package/dist/docs/player-bar.md +158 -0
- package/dist/docs/popover.md +200 -0
- package/dist/docs/progress-ring.md +70 -0
- package/dist/docs/radio-cards.md +82 -0
- package/dist/docs/radio-group.md +86 -0
- package/dist/docs/range-slider.md +64 -0
- package/dist/docs/repeat-picker.md +44 -0
- package/dist/docs/resizable.md +107 -0
- package/dist/docs/seek-bar.md +97 -0
- package/dist/docs/segmented.md +89 -0
- package/dist/docs/select.md +148 -0
- package/dist/docs/separator.md +76 -0
- package/dist/docs/side-nav.md +75 -0
- package/dist/docs/skeleton.md +89 -0
- package/dist/docs/slider.md +87 -0
- package/dist/docs/sortable.md +244 -0
- package/dist/docs/sparkline.md +56 -0
- package/dist/docs/spinner.md +69 -0
- package/dist/docs/status-pill.md +81 -0
- package/dist/docs/stepper.md +59 -0
- package/dist/docs/tab-bar.md +78 -0
- package/dist/docs/table-of-contents.md +43 -0
- package/dist/docs/table.md +714 -0
- package/dist/docs/tabs.md +140 -0
- package/dist/docs/tag-input.md +45 -0
- package/dist/docs/textarea.md +25 -0
- package/dist/docs/theme-toggle.md +85 -0
- package/dist/docs/theming.md +193 -0
- package/dist/docs/time-field.md +71 -0
- package/dist/docs/timeline.md +50 -0
- package/dist/docs/toast.md +53 -0
- package/dist/docs/toggle-group.md +83 -0
- package/dist/docs/toggle.md +38 -0
- package/dist/docs/toolbar.md +97 -0
- package/dist/docs/tooltip.md +102 -0
- package/dist/docs/tree.md +295 -0
- package/dist/docs/trend.md +50 -0
- package/dist/filter-bar/index.js +6 -6
- package/dist/header/index.js +6 -6
- package/dist/icon-picker/index.js +5 -5
- package/dist/icons/arrow-path.d.ts +3 -0
- package/dist/icons/arrow-path.d.ts.map +1 -0
- package/dist/icons/arrows-right-left.d.ts +3 -0
- package/dist/icons/arrows-right-left.d.ts.map +1 -0
- package/dist/icons/backward.d.ts +3 -0
- package/dist/icons/backward.d.ts.map +1 -0
- package/dist/icons/forward.d.ts +3 -0
- package/dist/icons/forward.d.ts.map +1 -0
- package/dist/icons/heart-solid.d.ts +3 -0
- package/dist/icons/heart-solid.d.ts.map +1 -0
- package/dist/icons/heart.d.ts +3 -0
- package/dist/icons/heart.d.ts.map +1 -0
- package/dist/icons/musical-note.d.ts +3 -0
- package/dist/icons/musical-note.d.ts.map +1 -0
- package/dist/icons/pause.d.ts +3 -0
- package/dist/icons/pause.d.ts.map +1 -0
- package/dist/icons/play.d.ts +3 -0
- package/dist/icons/play.d.ts.map +1 -0
- package/dist/icons/queue-list.d.ts +3 -0
- package/dist/icons/queue-list.d.ts.map +1 -0
- package/dist/icons/speaker-wave.d.ts +3 -0
- package/dist/icons/speaker-wave.d.ts.map +1 -0
- package/dist/icons/speaker-x-mark.d.ts +3 -0
- package/dist/icons/speaker-x-mark.d.ts.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/keypad/index.js +5 -5
- package/dist/lib.js +86 -80
- package/dist/load-more/index.js +5 -5
- package/dist/marquee/index.d.ts +15 -0
- package/dist/marquee/index.d.ts.map +1 -0
- package/dist/marquee/index.js +90 -0
- package/dist/menu/index.d.ts +7 -1
- package/dist/menu/index.d.ts.map +1 -1
- package/dist/menu/index.js +222 -178
- package/dist/money-input/index.js +54 -54
- package/dist/month-picker/index.js +11 -11
- package/dist/number-field/index.js +5 -5
- package/dist/pagination/index.js +12 -12
- package/dist/player-bar/index.d.ts +11 -0
- package/dist/player-bar/index.d.ts.map +1 -0
- package/dist/player-bar/index.js +17 -0
- package/dist/radio-cards/index.d.ts +2 -1
- package/dist/radio-cards/index.d.ts.map +1 -1
- package/dist/radio-cards/index.js +3 -3
- package/dist/range-slider/index.js +11 -11
- package/dist/repeat-picker/index.js +5 -5
- package/dist/resizable/index.js +22 -22
- package/dist/seek-bar/index.d.ts +26 -0
- package/dist/seek-bar/index.d.ts.map +1 -0
- package/dist/seek-bar/index.js +121 -0
- package/dist/segmented/index.d.ts +3 -2
- package/dist/segmented/index.d.ts.map +1 -1
- package/dist/segmented/index.js +19 -18
- package/dist/select/index.js +21 -21
- package/dist/slider/index.d.ts +2 -1
- package/dist/slider/index.d.ts.map +1 -1
- package/dist/sortable/index.d.ts +13 -1
- package/dist/sortable/index.d.ts.map +1 -1
- package/dist/sortable/index.js +74 -55
- package/dist/sortable/shared.js +14 -14
- package/dist/sortable/tree.js +17 -17
- package/dist/sparkline/index.js +4 -4
- package/dist/stepper/index.js +13 -13
- package/dist/tab-bar/index.d.ts +4 -2
- package/dist/tab-bar/index.d.ts.map +1 -1
- package/dist/tab-bar/index.js +24 -19
- package/dist/table/index.js +26 -26
- package/dist/table/selection.js +9 -9
- package/dist/table-of-contents/index.js +11 -11
- package/dist/tag-input/index.js +5 -5
- package/dist/textarea/index.d.ts +6 -2
- package/dist/textarea/index.d.ts.map +1 -1
- package/dist/textarea/index.js +2 -1
- package/dist/theme-toggle/index.js +4 -4
- package/dist/theme.css +143 -0
- package/dist/time-field/index.js +21 -21
- package/dist/toast/index.d.ts.map +1 -1
- package/dist/toast/index.js +41 -41
- package/dist/tooltip/index.d.ts +9 -3
- package/dist/tooltip/index.d.ts.map +1 -1
- package/dist/tooltip/index.js +19 -16
- package/dist/tree/index.js +34 -34
- package/dist/trend/index.js +5 -5
- package/dist/utils/duration.d.ts +3 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/duration.js +7 -0
- package/dist/utils/messages.d.ts +3 -0
- package/dist/utils/messages.d.ts.map +1 -1
- package/dist/utils/messages.js +4 -1
- package/dist/utils/slot.d.ts +5 -2
- package/dist/utils/slot.d.ts.map +1 -1
- package/dist/utils/slot.js +16 -11
- package/dist/utils/swipe.d.ts +7 -0
- package/dist/utils/swipe.d.ts.map +1 -1
- package/dist/utils/swipe.js +45 -25
- package/dist/utils/useAnchoredPopup.d.ts +2 -1
- package/dist/utils/useAnchoredPopup.d.ts.map +1 -1
- package/dist/utils/useAnchoredPopup.js +10 -5
- package/dist/utils/useHeightVar.d.ts +7 -0
- package/dist/utils/useHeightVar.d.ts.map +1 -0
- package/dist/utils/useHeightVar.js +17 -0
- package/dist/utils/useMediaPlayer.d.ts +38 -0
- package/dist/utils/useMediaPlayer.d.ts.map +1 -0
- package/dist/utils/useMediaPlayer.js +91 -0
- package/dist/utils/useMediaSession.d.ts +24 -0
- package/dist/utils/useMediaSession.d.ts.map +1 -0
- package/dist/utils/useMediaSession.js +76 -0
- package/dist/utils/useVirtualList.d.ts +6 -1
- package/dist/utils/useVirtualList.d.ts.map +1 -1
- package/dist/utils/useVirtualList.js +12 -12
- package/dist/zen.css +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
Glass panels for grouping content, and stats for single figures.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { Card, CardHeader, CardTitle, CardDescription, Stat, StatRow } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Goal
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import {
|
|
15
|
+
Button,
|
|
16
|
+
buttonVariants,
|
|
17
|
+
Card,
|
|
18
|
+
CardHeader,
|
|
19
|
+
CardTitle,
|
|
20
|
+
Menu,
|
|
21
|
+
MenuContent,
|
|
22
|
+
MenuItem,
|
|
23
|
+
MenuTrigger,
|
|
24
|
+
ProgressRing,
|
|
25
|
+
} from '@rinzai/zen';
|
|
26
|
+
// Icons from Heroicons (https://heroicons.com): Ellipsis (ellipsis-horizontal).
|
|
27
|
+
|
|
28
|
+
export default function Goal() {
|
|
29
|
+
return (
|
|
30
|
+
<Card className="w-full max-w-sm">
|
|
31
|
+
<CardHeader>
|
|
32
|
+
<CardTitle>Emergency fund</CardTitle>
|
|
33
|
+
<Menu>
|
|
34
|
+
<MenuTrigger
|
|
35
|
+
aria-label="Goal actions"
|
|
36
|
+
className={buttonVariants({ variant: 'ghost', size: 'icon' })}
|
|
37
|
+
>
|
|
38
|
+
<Ellipsis />
|
|
39
|
+
</MenuTrigger>
|
|
40
|
+
<MenuContent>
|
|
41
|
+
<MenuItem>Edit</MenuItem>
|
|
42
|
+
</MenuContent>
|
|
43
|
+
</Menu>
|
|
44
|
+
</CardHeader>
|
|
45
|
+
<div className="flex items-center gap-4">
|
|
46
|
+
<ProgressRing value={0.64} label="Emergency fund">
|
|
47
|
+
<span className="text-sm font-semibold tabular-nums">64%</span>
|
|
48
|
+
</ProgressRing>
|
|
49
|
+
<div className="flex flex-col gap-1">
|
|
50
|
+
<span className="text-muted-foreground text-sm">$6,400 of $10,000</span>
|
|
51
|
+
<Button size="sm" variant="secondary" className="self-start">
|
|
52
|
+
Add money
|
|
53
|
+
</Button>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</Card>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Stats
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { Stat, StatRow } from '@rinzai/zen';
|
|
65
|
+
|
|
66
|
+
export default function Stats() {
|
|
67
|
+
return (
|
|
68
|
+
<StatRow className="w-full max-w-3xl">
|
|
69
|
+
<Stat label="Income" value="$8,450" hint="+4% on last month" />
|
|
70
|
+
<Stat label="Spent" value="$5,120" tone="negative" />
|
|
71
|
+
<Stat label="Net this month" value="$3,330" tone="positive" />
|
|
72
|
+
</StatRow>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Morph
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
import { Button, Card, CardDescription, CardHeader, CardTitle, Sparkline } from '@rinzai/zen';
|
|
81
|
+
import { startTransition, useState, ViewTransition } from 'react';
|
|
82
|
+
|
|
83
|
+
const accounts = [
|
|
84
|
+
{ id: 'checking', name: 'Checking', balance: '$4,280.15', trend: [31, 34, 30, 38, 36, 42, 40, 45] },
|
|
85
|
+
{ id: 'savings', name: 'Savings', balance: '$12,940.00', trend: [80, 82, 83, 85, 86, 88, 91, 94] },
|
|
86
|
+
{ id: 'card', name: 'Credit card', balance: '−$612.40', trend: [12, 18, 15, 22, 27, 21, 30, 26] },
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
export default function Morph() {
|
|
90
|
+
const [open, setOpen] = useState<string | null>(null);
|
|
91
|
+
const go = (id: string | null) => startTransition(() => setOpen(id));
|
|
92
|
+
const account = accounts.find((a) => a.id === open);
|
|
93
|
+
|
|
94
|
+
if (account)
|
|
95
|
+
return (
|
|
96
|
+
<ViewTransition name={`account-${account.id}`} share="zen-morph">
|
|
97
|
+
<Card className="w-full max-w-md">
|
|
98
|
+
<CardHeader>
|
|
99
|
+
<CardTitle>{account.name}</CardTitle>
|
|
100
|
+
<Button size="sm" variant="ghost" onClick={() => go(null)}>
|
|
101
|
+
Back
|
|
102
|
+
</Button>
|
|
103
|
+
</CardHeader>
|
|
104
|
+
<p className="text-3xl font-semibold tabular-nums">{account.balance}</p>
|
|
105
|
+
<CardDescription className="mt-1">Last 8 weeks</CardDescription>
|
|
106
|
+
<Sparkline values={account.trend} className="mt-4 h-24 w-full" />
|
|
107
|
+
</Card>
|
|
108
|
+
</ViewTransition>
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div className="grid w-full max-w-md gap-3">
|
|
113
|
+
{accounts.map((a) => (
|
|
114
|
+
<ViewTransition key={a.id} name={`account-${a.id}`} share="zen-morph">
|
|
115
|
+
<Card className="p-0 md:p-0">
|
|
116
|
+
<button
|
|
117
|
+
type="button"
|
|
118
|
+
onClick={() => go(a.id)}
|
|
119
|
+
className="flex w-full items-center justify-between rounded-xl p-4 text-left"
|
|
120
|
+
>
|
|
121
|
+
<span className="font-medium">{a.name}</span>
|
|
122
|
+
<span className="tabular-nums">{a.balance}</span>
|
|
123
|
+
</button>
|
|
124
|
+
</Card>
|
|
125
|
+
</ViewTransition>
|
|
126
|
+
))}
|
|
127
|
+
</div>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## API reference
|
|
133
|
+
|
|
134
|
+
### Card
|
|
135
|
+
|
|
136
|
+
Glass panel whose border catches the pointer light. For a title with an
|
|
137
|
+
action beside it, start it with a CardHeader holding a CardTitle and the action.
|
|
138
|
+
|
|
139
|
+
No props of its own; it accepts the props of the element it renders.
|
|
140
|
+
|
|
141
|
+
### CardHeader
|
|
142
|
+
|
|
143
|
+
The top row of a Card: its title, and an action (a button, a menu) at the end.
|
|
144
|
+
|
|
145
|
+
No props of its own; it accepts the props of the element it renders.
|
|
146
|
+
|
|
147
|
+
### CardTitle
|
|
148
|
+
|
|
149
|
+
The card's title: an h4 by default; with `asChild`, your own heading (an h2, say) gets its look.
|
|
150
|
+
|
|
151
|
+
| Prop | Type | Default | Description |
|
|
152
|
+
| --- | --- | --- | --- |
|
|
153
|
+
| `asChild` | `boolean` | | Put the title's look on your own heading element instead of an h4. |
|
|
154
|
+
|
|
155
|
+
### CardDescription
|
|
156
|
+
|
|
157
|
+
A line under the CardTitle: what the card is about, or a figure's context ("₹12L at 8.5% · 20 years").
|
|
158
|
+
|
|
159
|
+
No props of its own; it accepts the props of the element it renders.
|
|
160
|
+
|
|
161
|
+
### Stat
|
|
162
|
+
|
|
163
|
+
A single figure with a label, e.g. "Revenue $12,400".
|
|
164
|
+
|
|
165
|
+
| Prop | Type | Default | Description |
|
|
166
|
+
| --- | --- | --- | --- |
|
|
167
|
+
| `label` (required) | `string` | | |
|
|
168
|
+
| `value` (required) | `ReactNode` | | |
|
|
169
|
+
| `children` | `ReactNode` | | Under the figure: how it got there, like a Sparkline. |
|
|
170
|
+
| `className` | `string` | | |
|
|
171
|
+
| `hint` | `ReactNode` | | |
|
|
172
|
+
| `tone` | `"default" \| "negative" \| "positive"` | `default` | |
|
|
173
|
+
|
|
174
|
+
### StatRow
|
|
175
|
+
|
|
176
|
+
Row of stats: two columns on phones (an odd last one spans both), three from `sm` up.
|
|
177
|
+
|
|
178
|
+
| Prop | Type | Default | Description |
|
|
179
|
+
| --- | --- | --- | --- |
|
|
180
|
+
| `className` | `string` | | |
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Carousel
|
|
2
|
+
|
|
3
|
+
Slides in a row that snap as you swipe or scroll, with glass buttons and dots that light the current one beneath, and the arrow keys. Native scrolling, so it follows the finger exactly.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { Carousel, CarouselContent, CarouselItem, CarouselControls, CarouselPrevious, CarouselNext, CarouselDots } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Default
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import {
|
|
15
|
+
Card,
|
|
16
|
+
Carousel,
|
|
17
|
+
CarouselContent,
|
|
18
|
+
CarouselControls,
|
|
19
|
+
CarouselDots,
|
|
20
|
+
CarouselItem,
|
|
21
|
+
CarouselNext,
|
|
22
|
+
CarouselPrevious,
|
|
23
|
+
ProgressRing,
|
|
24
|
+
} from '@rinzai/zen';
|
|
25
|
+
|
|
26
|
+
const GOALS = [
|
|
27
|
+
{ name: 'Emergency fund', saved: 6400, target: 10000 },
|
|
28
|
+
{ name: 'New laptop', saved: 1150, target: 1800 },
|
|
29
|
+
{ name: 'Trip to Kyoto', saved: 2100, target: 4500 },
|
|
30
|
+
{ name: 'Wedding gift', saved: 300, target: 300 },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const usd = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
|
|
34
|
+
|
|
35
|
+
/** One slide at a time, with buttons and dots below. Swipe or scroll it too, or focus it and use the arrow keys. */
|
|
36
|
+
export default function Default() {
|
|
37
|
+
return (
|
|
38
|
+
<Carousel aria-label="Savings goals" className="w-full max-w-sm">
|
|
39
|
+
<CarouselContent>
|
|
40
|
+
{GOALS.map((goal) => (
|
|
41
|
+
<CarouselItem key={goal.name}>
|
|
42
|
+
<Card className="flex items-center gap-5">
|
|
43
|
+
<ProgressRing value={goal.saved / goal.target} label={goal.name}>
|
|
44
|
+
<span className="text-sm font-semibold tabular-nums">
|
|
45
|
+
{Math.round((goal.saved / goal.target) * 100)}%
|
|
46
|
+
</span>
|
|
47
|
+
</ProgressRing>
|
|
48
|
+
<div className="flex min-w-0 flex-col gap-1">
|
|
49
|
+
<span className="truncate font-medium">{goal.name}</span>
|
|
50
|
+
<span className="text-muted-foreground text-sm tabular-nums">
|
|
51
|
+
{usd.format(goal.saved)} of {usd.format(goal.target)}
|
|
52
|
+
</span>
|
|
53
|
+
</div>
|
|
54
|
+
</Card>
|
|
55
|
+
</CarouselItem>
|
|
56
|
+
))}
|
|
57
|
+
</CarouselContent>
|
|
58
|
+
<CarouselControls>
|
|
59
|
+
<CarouselPrevious />
|
|
60
|
+
<CarouselDots />
|
|
61
|
+
<CarouselNext />
|
|
62
|
+
</CarouselControls>
|
|
63
|
+
</Carousel>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Several
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { Carousel, CarouselContent, CarouselControls, CarouselItem, CarouselNext, CarouselPrevious } from '@rinzai/zen';
|
|
72
|
+
|
|
73
|
+
const CATEGORIES = [
|
|
74
|
+
{ name: 'Groceries', spent: '$412', chart: 6 },
|
|
75
|
+
{ name: 'Rent', spent: '$1,600', chart: 7 },
|
|
76
|
+
{ name: 'Transport', spent: '$96', chart: 1 },
|
|
77
|
+
{ name: 'Eating out', spent: '$238', chart: 2 },
|
|
78
|
+
{ name: 'Subscriptions', spent: '$54', chart: 5 },
|
|
79
|
+
{ name: 'Health', spent: '$120', chart: 3 },
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Several slides in view: size the items (here a half, then a third on wider
|
|
84
|
+
* screens). It snaps to each; the buttons sit together at the end, each gone when there's no further to go.
|
|
85
|
+
*/
|
|
86
|
+
export default function Several() {
|
|
87
|
+
return (
|
|
88
|
+
<Carousel aria-label="Spending by category" className="w-full max-w-xl">
|
|
89
|
+
<CarouselContent className="gap-3">
|
|
90
|
+
{CATEGORIES.map((c) => (
|
|
91
|
+
<CarouselItem key={c.name} className="basis-[calc(50%-0.375rem)] sm:basis-[calc(33.333%-0.5rem)]">
|
|
92
|
+
<div
|
|
93
|
+
className="border-tint/10 flex h-28 flex-col justify-end gap-0.5 rounded-xl border p-4"
|
|
94
|
+
style={{
|
|
95
|
+
// The chart palette, so each category looks as it does in charts.
|
|
96
|
+
background: `linear-gradient(160deg, color-mix(in oklch, var(--chart-${c.chart}) 35%, transparent), color-mix(in oklch, var(--chart-${c.chart}) 6%, transparent))`,
|
|
97
|
+
}}
|
|
98
|
+
>
|
|
99
|
+
<span className="text-muted-foreground text-xs">{c.name}</span>
|
|
100
|
+
<span className="text-lg font-semibold tabular-nums">{c.spent}</span>
|
|
101
|
+
</div>
|
|
102
|
+
</CarouselItem>
|
|
103
|
+
))}
|
|
104
|
+
</CarouselContent>
|
|
105
|
+
<CarouselControls className="justify-end">
|
|
106
|
+
<CarouselPrevious />
|
|
107
|
+
<CarouselNext />
|
|
108
|
+
</CarouselControls>
|
|
109
|
+
</Carousel>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## API reference
|
|
115
|
+
|
|
116
|
+
### Carousel
|
|
117
|
+
|
|
118
|
+
Slides in a row that scrolls sideways and snaps to each one: swipe, scroll,
|
|
119
|
+
use the arrow keys once it has focus, or the CarouselPrevious and
|
|
120
|
+
CarouselNext buttons. Put a CarouselContent of CarouselItems inside, then a
|
|
121
|
+
CarouselControls of the buttons and CarouselDots if you want them. A slide is as wide as the
|
|
122
|
+
carousel unless you size it (e.g. `basis-1/3` for three in view).
|
|
123
|
+
|
|
124
|
+
No props of its own; it accepts the props of the element it renders.
|
|
125
|
+
|
|
126
|
+
### CarouselContent
|
|
127
|
+
|
|
128
|
+
The scrolling row of slides.
|
|
129
|
+
|
|
130
|
+
No props of its own; it accepts the props of the element it renders.
|
|
131
|
+
|
|
132
|
+
### CarouselItem
|
|
133
|
+
|
|
134
|
+
One slide: it's announced as which of how many.
|
|
135
|
+
|
|
136
|
+
No props of its own; it accepts the props of the element it renders.
|
|
137
|
+
|
|
138
|
+
### CarouselControls
|
|
139
|
+
|
|
140
|
+
The row under the slides: CarouselPrevious at the start, CarouselNext at the end, CarouselDots between.
|
|
141
|
+
|
|
142
|
+
No props of its own; it accepts the props of the element it renders.
|
|
143
|
+
|
|
144
|
+
### CarouselPrevious
|
|
145
|
+
|
|
146
|
+
Scroll back one slide: a round glass button, gone at the first (keeping its
|
|
147
|
+
place, so the controls don't shift). Put it in CarouselControls, under the
|
|
148
|
+
slides, where it never covers them.
|
|
149
|
+
|
|
150
|
+
No props of its own; it accepts the props of the element it renders.
|
|
151
|
+
|
|
152
|
+
### CarouselNext
|
|
153
|
+
|
|
154
|
+
Scroll on one slide: a round glass button, gone at the last.
|
|
155
|
+
|
|
156
|
+
No props of its own; it accepts the props of the element it renders.
|
|
157
|
+
|
|
158
|
+
### CarouselDots
|
|
159
|
+
|
|
160
|
+
A dot for each place it can scroll to, the current one drawn out long and lit; each goes there.
|
|
161
|
+
|
|
162
|
+
No props of its own; it accepts the props of the element it renders.
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Chart
|
|
2
|
+
|
|
3
|
+
Areas, lines and bars on one axis, a donut and an allocation bar: plain SVG that draws itself in, with a crosshair tooltip, keyboard reading, a legend and a table for screen readers.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { Chart, ChartArea, ChartLine, ChartBar, ChartReference, ChartTooltipCard, DonutChart, AllocationBar } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Balance
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Chart, ChartArea, ChartReference } from '@rinzai/zen';
|
|
15
|
+
|
|
16
|
+
const MONTHS = [
|
|
17
|
+
'2026-04',
|
|
18
|
+
'2026-05',
|
|
19
|
+
'2026-06',
|
|
20
|
+
'2026-07',
|
|
21
|
+
'2026-08',
|
|
22
|
+
'2026-09',
|
|
23
|
+
'2026-10',
|
|
24
|
+
'2026-11',
|
|
25
|
+
'2026-12',
|
|
26
|
+
'2027-01',
|
|
27
|
+
'2027-02',
|
|
28
|
+
'2027-03',
|
|
29
|
+
];
|
|
30
|
+
const BALANCE = [4.2, 5.1, 3.8, 4.6, 6.2, 7.1, 6.4, 7.9, 8.8, 7.6, 9.4, 10.2].map((l) => l * 100000);
|
|
31
|
+
const TODAY = '2026-09';
|
|
32
|
+
// One series split in two at today: solid where it happened, dashed where it's projected.
|
|
33
|
+
const DATA = MONTHS.map((month, i) => ({
|
|
34
|
+
month,
|
|
35
|
+
balance: month <= TODAY ? BALANCE[i] : null,
|
|
36
|
+
projected: month >= TODAY ? BALANCE[i] : null,
|
|
37
|
+
}));
|
|
38
|
+
const label = (m: string) => new Date(`${m}-01T00:00Z`).toLocaleString('en-IN', { month: 'short', timeZone: 'UTC' });
|
|
39
|
+
const money = new Intl.NumberFormat('en-IN', {
|
|
40
|
+
style: 'currency',
|
|
41
|
+
currency: 'INR',
|
|
42
|
+
notation: 'compact',
|
|
43
|
+
maximumFractionDigits: 1,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/** An area in the theme's glow: solid up to today, dashed ahead, with a "Today" marker. Point at it, or focus it and use the arrow keys. */
|
|
47
|
+
export default function Balance() {
|
|
48
|
+
return (
|
|
49
|
+
<Chart
|
|
50
|
+
data={DATA}
|
|
51
|
+
x="month"
|
|
52
|
+
label="Balance over time"
|
|
53
|
+
summary="Balance grows from ₹4.2L in April to a projected ₹10.2L next March."
|
|
54
|
+
formatX={label}
|
|
55
|
+
formatY={(v) => money.format(v)}
|
|
56
|
+
className="w-full max-w-2xl"
|
|
57
|
+
>
|
|
58
|
+
<ChartArea dataKey="balance" label="Balance" color="oklch(var(--glow))" />
|
|
59
|
+
<ChartArea dataKey="projected" label="Projected" color="oklch(var(--glow-2))" dashed />
|
|
60
|
+
<ChartReference x={TODAY} label="Today" />
|
|
61
|
+
</Chart>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Cashflow
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { Chart, ChartBar, ChartLine, ChartReference } from '@rinzai/zen';
|
|
70
|
+
|
|
71
|
+
const DATA = [
|
|
72
|
+
{ month: 'Apr', income: 92000, spending: 61000 },
|
|
73
|
+
{ month: 'May', income: 92000, spending: 74000 },
|
|
74
|
+
{ month: 'Jun', income: 98000, spending: 58000 },
|
|
75
|
+
{ month: 'Jul', income: 98000, spending: 103000 },
|
|
76
|
+
{ month: 'Aug', income: 98000, spending: 66000 },
|
|
77
|
+
{ month: 'Sep', income: 112000, spending: 71000 },
|
|
78
|
+
{ month: 'Oct', income: 112000, spending: 69000 },
|
|
79
|
+
{ month: 'Nov', income: 112000, spending: 80000 },
|
|
80
|
+
].map((r) => ({ ...r, net: r.income - r.spending }));
|
|
81
|
+
const inr = new Intl.NumberFormat('en-IN', {
|
|
82
|
+
style: 'currency',
|
|
83
|
+
currency: 'INR',
|
|
84
|
+
notation: 'compact',
|
|
85
|
+
maximumFractionDigits: 1,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
/** Bars grouped by month with a line on the same axis; months still to come are faded. */
|
|
89
|
+
export default function Cashflow() {
|
|
90
|
+
return (
|
|
91
|
+
<Chart
|
|
92
|
+
data={DATA}
|
|
93
|
+
x="month"
|
|
94
|
+
label="Income and spending by month"
|
|
95
|
+
formatY={(v) => inr.format(v)}
|
|
96
|
+
className="w-full max-w-2xl"
|
|
97
|
+
>
|
|
98
|
+
<ChartBar dataKey="income" label="Income" dim={(_, i) => i > 5} />
|
|
99
|
+
<ChartBar dataKey="spending" label="Spending" dim={(_, i) => i > 5} />
|
|
100
|
+
<ChartLine dataKey="net" label="Net" color="var(--chart-3)" />
|
|
101
|
+
<ChartReference y={0} tone="negative" />
|
|
102
|
+
</Chart>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Lines
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import { Chart, ChartLine } from '@rinzai/zen';
|
|
111
|
+
|
|
112
|
+
const DATA = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'].map((day, i) => ({
|
|
113
|
+
day,
|
|
114
|
+
web: [420, 480, 510, 470, 560, 690, 640][i],
|
|
115
|
+
ios: [310, 330, 360, 390, 380, 450, 470][i],
|
|
116
|
+
android: [220, 260, 250, 300, 330, 310, 360][i],
|
|
117
|
+
}));
|
|
118
|
+
|
|
119
|
+
/** Several series in the chart palette, in the order they're written; the legend appears for two or more. */
|
|
120
|
+
export default function Lines() {
|
|
121
|
+
return (
|
|
122
|
+
<Chart data={DATA} x="day" label="Sessions by platform" height={220} className="w-full max-w-2xl">
|
|
123
|
+
<ChartLine dataKey="web" label="Web" />
|
|
124
|
+
<ChartLine dataKey="ios" label="iOS" />
|
|
125
|
+
<ChartLine dataKey="android" label="Android" />
|
|
126
|
+
</Chart>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Donut
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
import { DonutChart, paletteColor } from '@rinzai/zen';
|
|
135
|
+
|
|
136
|
+
const SPENDING = [
|
|
137
|
+
{ key: 'home', label: 'Home', value: 28000 },
|
|
138
|
+
{ key: 'food', label: 'Food', value: 14500 },
|
|
139
|
+
{ key: 'travel', label: 'Travel', value: 9200 },
|
|
140
|
+
{ key: 'fun', label: 'Fun', value: 6100 },
|
|
141
|
+
{ key: 'other', label: 'Other', value: 3400 },
|
|
142
|
+
];
|
|
143
|
+
const total = SPENDING.reduce((s, x) => s + x.value, 0);
|
|
144
|
+
const inr = (v: number) =>
|
|
145
|
+
new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR', maximumFractionDigits: 0 }).format(v);
|
|
146
|
+
|
|
147
|
+
/** Parts of a whole with the total in the middle, and a legend of your own beside it, in the chart's colours (paletteColor). */
|
|
148
|
+
export default function Donut() {
|
|
149
|
+
return (
|
|
150
|
+
<div className="flex flex-wrap items-center gap-8">
|
|
151
|
+
<DonutChart items={SPENDING} label="Spending by category" formatValue={inr}>
|
|
152
|
+
<div>
|
|
153
|
+
<div className="text-muted-foreground text-[0.68rem] tracking-[0.1em] uppercase">Spent</div>
|
|
154
|
+
<div className="text-lg font-semibold tracking-tight">{inr(total)}</div>
|
|
155
|
+
</div>
|
|
156
|
+
</DonutChart>
|
|
157
|
+
<ul className="flex min-w-48 flex-col gap-2 text-sm">
|
|
158
|
+
{SPENDING.map((s, i) => (
|
|
159
|
+
<li key={s.key} className="flex items-center gap-2.5">
|
|
160
|
+
<span
|
|
161
|
+
className="size-2.5 rounded-[3px]"
|
|
162
|
+
style={{ background: paletteColor('chart', i, SPENDING.length) }}
|
|
163
|
+
/>
|
|
164
|
+
<span className="flex-1">{s.label}</span>
|
|
165
|
+
<span className="font-medium tabular-nums">{inr(s.value)}</span>
|
|
166
|
+
</li>
|
|
167
|
+
))}
|
|
168
|
+
</ul>
|
|
169
|
+
</div>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Allocation
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
import { AllocationBar, formatMoney } from '@rinzai/zen';
|
|
178
|
+
|
|
179
|
+
/** Where September's income went. */
|
|
180
|
+
export default function Allocation() {
|
|
181
|
+
return (
|
|
182
|
+
<AllocationBar
|
|
183
|
+
label="Income in September"
|
|
184
|
+
className="w-full max-w-md"
|
|
185
|
+
locale="en-US"
|
|
186
|
+
formatValue={(v) => formatMoney(v, 'USD', 'en-US', { showDecimals: false })}
|
|
187
|
+
items={[
|
|
188
|
+
{ key: 'bills', label: 'Bills', value: 182000 },
|
|
189
|
+
{ key: 'spending', label: 'Spending', value: 145600 },
|
|
190
|
+
{ key: 'savings', label: 'Savings', value: 96000 },
|
|
191
|
+
{ key: 'investing', label: 'Investing', value: 50000 },
|
|
192
|
+
{ key: 'left', label: 'Left over', value: 26400 },
|
|
193
|
+
]}
|
|
194
|
+
/>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## API reference
|
|
200
|
+
|
|
201
|
+
### Chart
|
|
202
|
+
|
|
203
|
+
A chart on one axis: areas, lines and bars over rows of data (e.g. months),
|
|
204
|
+
with a recessive grid, a crosshair and a tooltip listing every series at the
|
|
205
|
+
pointer (or keyboard: focus it and use the arrow keys), a legend for two or
|
|
206
|
+
more series, and a table of the values for screen readers. Series draw in
|
|
207
|
+
as they appear. Colours default to the chart palette (--chart-1…8) in the
|
|
208
|
+
order the series are written; give each its own `color` for meaning (e.g.
|
|
209
|
+
the theme's glow).
|
|
210
|
+
|
|
211
|
+
| Prop | Type | Default | Description |
|
|
212
|
+
| --- | --- | --- | --- |
|
|
213
|
+
| `children` (required) | `ReactNode` | | ChartArea, ChartLine, ChartBar and ChartReference parts. |
|
|
214
|
+
| `data` (required) | `readonly T[]` | | One row per point on the x axis (e.g. a month). |
|
|
215
|
+
| `label` (required) | `string` | | Names the chart for screen readers. |
|
|
216
|
+
| `x` (required) | `string` | | The row field placed along the x axis. |
|
|
217
|
+
| `className` | `string` | | |
|
|
218
|
+
| `formatTooltipX` | `((value: T[X]) => string)` | | The tooltip's title for an x value (defaults to formatX). |
|
|
219
|
+
| `formatX` | `((value: T[X]) => string)` | | Axis labels for x values. |
|
|
220
|
+
| `formatY` | `((value: number) => string)` | `(n: number) => compactFormat.format(n)` | Axis ticks and tooltip values (defaults to compact numbers: 1.2K). |
|
|
221
|
+
| `height` | `number` | `240` | Height in px, including the axis labels. |
|
|
222
|
+
| `legend` | `boolean` | | Show the legend. Defaults to on for two or more series, or a bar's `dimLabel`. |
|
|
223
|
+
| `palette` | `ChartPalette` | `chart` | Colours for series that don't give their own: the categorical palette (default), or shades of the theme's glow. |
|
|
224
|
+
| `renderTooltip` | `((row: T, index: number) => ReactNode)` | | Your own tooltip for a row (build it from ChartTooltipCard). |
|
|
225
|
+
| `summary` | `string` | | A sentence on what the chart shows, for screen readers (e.g. its highest and lowest points). |
|
|
226
|
+
|
|
227
|
+
### ChartArea
|
|
228
|
+
|
|
229
|
+
A line with a soft fill down to the baseline.
|
|
230
|
+
|
|
231
|
+
| Prop | Type | Default | Description |
|
|
232
|
+
| --- | --- | --- | --- |
|
|
233
|
+
| `dataKey` (required) | `string` | | The row field holding this series' values (numbers; null for none). |
|
|
234
|
+
| `label` (required) | `string` | | Its name in the legend, the tooltip and the table. |
|
|
235
|
+
| `color` | `string` | | Any CSS colour. Defaults to the next of --chart-1…8. |
|
|
236
|
+
| `curve` | `"linear" \| "monotone"` | | Smooth (default) or straight between points. |
|
|
237
|
+
| `dashed` | `boolean` | | Dashed (e.g. a projection). |
|
|
238
|
+
|
|
239
|
+
### ChartLine
|
|
240
|
+
|
|
241
|
+
A 2px line. Gaps (null values) break it, so one series can be split into solid and dashed parts.
|
|
242
|
+
|
|
243
|
+
| Prop | Type | Default | Description |
|
|
244
|
+
| --- | --- | --- | --- |
|
|
245
|
+
| `dataKey` (required) | `string` | | The row field holding this series' values (numbers; null for none). |
|
|
246
|
+
| `label` (required) | `string` | | Its name in the legend, the tooltip and the table. |
|
|
247
|
+
| `color` | `string` | | Any CSS colour. Defaults to the next of --chart-1…8. |
|
|
248
|
+
| `curve` | `"linear" \| "monotone"` | | Smooth (default) or straight between points. |
|
|
249
|
+
| `dashed` | `boolean` | | Dashed (e.g. a projection). |
|
|
250
|
+
|
|
251
|
+
### ChartBar
|
|
252
|
+
|
|
253
|
+
Bars, grouped with the other bar series, growing from the baseline.
|
|
254
|
+
|
|
255
|
+
| Prop | Type | Default | Description |
|
|
256
|
+
| --- | --- | --- | --- |
|
|
257
|
+
| `dataKey` (required) | `string` | | The row field holding this series' values (numbers; null for none). |
|
|
258
|
+
| `label` (required) | `string` | | Its name in the legend, the tooltip and the table. |
|
|
259
|
+
| `color` | `string` | | Any CSS colour. Defaults to the next of --chart-1…8. |
|
|
260
|
+
| `dim` | `((row: Row, index: number) => boolean)` | | Rows whose bar is faded, e.g. months still to come. |
|
|
261
|
+
| `dimLabel` | `string` | | What the faded bars mean, e.g. "Planned": the legend gets a faded key for it (and shows, even for one series). |
|
|
262
|
+
|
|
263
|
+
### ChartReference
|
|
264
|
+
|
|
265
|
+
A marker across the plot: a horizontal line at `y` (e.g. zero), or a vertical one at the row whose x is `x` (e.g. today).
|
|
266
|
+
|
|
267
|
+
| Prop | Type | Default | Description |
|
|
268
|
+
| --- | --- | --- | --- |
|
|
269
|
+
| `dashed` | `boolean` | | Vertical lines are dashed unless `dashed={false}`; horizontal ones solid unless `dashed`. |
|
|
270
|
+
| `label` | `string` | | Text beside a vertical line, e.g. "Today". |
|
|
271
|
+
| `tone` | `"muted" \| "negative"` | | Destructive for a line that warns (e.g. below zero). |
|
|
272
|
+
| `x` | `unknown` | | A vertical line at the row whose x field equals this. |
|
|
273
|
+
| `y` | `number` | | A horizontal line at this value. |
|
|
274
|
+
|
|
275
|
+
### ChartTooltipCard
|
|
276
|
+
|
|
277
|
+
The tooltip's card: a title and one row per series, the value first and the
|
|
278
|
+
series keyed by a short stroke of its colour. Use it in `renderTooltip` to
|
|
279
|
+
show your own rows.
|
|
280
|
+
|
|
281
|
+
| Prop | Type | Default | Description |
|
|
282
|
+
| --- | --- | --- | --- |
|
|
283
|
+
| `rows` (required) | `{ label: string; value: string; color?: string \| undefined; dashed?: boolean \| undefined; }[]` | | |
|
|
284
|
+
| `title` (required) | `ReactNode` | | |
|
|
285
|
+
| `className` | `string` | | |
|
|
286
|
+
|
|
287
|
+
### DonutChart
|
|
288
|
+
|
|
289
|
+
A ring of parts of a whole (e.g. spending by category), with your content in
|
|
290
|
+
the middle (e.g. the total). Segments are parted by a small gap, with
|
|
291
|
+
rounded corners; pointing at one (or focusing it) lifts it and shows its
|
|
292
|
+
value. A part too small to show at its share is drawn as a pill, the
|
|
293
|
+
narrowest segment, taking the room from the larger parts in proportion. Best
|
|
294
|
+
for a handful of parts: past about six, use bars. Colours default to the
|
|
295
|
+
chart palette in order.
|
|
296
|
+
|
|
297
|
+
| Prop | Type | Default | Description |
|
|
298
|
+
| --- | --- | --- | --- |
|
|
299
|
+
| `items` (required) | `{ key: string; label: string; value: number; color?: string \| undefined; }[]` | | The parts, in order round the ring from 12 o'clock. |
|
|
300
|
+
| `label` (required) | `string` | | Names the chart for screen readers. |
|
|
301
|
+
| `children` | `ReactNode` | | Content in the middle, e.g. the total. |
|
|
302
|
+
| `className` | `string` | | |
|
|
303
|
+
| `formatValue` | `((value: number) => string)` | | Values in the tooltip and for screen readers. |
|
|
304
|
+
| `palette` | `ChartPalette` | `chart` | Colours for items that don't give their own: the categorical palette (default), or shades of the theme's glow. |
|
|
305
|
+
| `size` | `number` | `200` | Diameter in px. |
|
|
306
|
+
| `thickness` | `number` | `0.32` | Ring thickness as a share of the radius. |
|
|
307
|
+
|
|
308
|
+
### AllocationBar
|
|
309
|
+
|
|
310
|
+
Where a whole went, as one bar split into its parts (e.g. income across
|
|
311
|
+
spending, savings and bills), with a legend of each part's value and share.
|
|
312
|
+
Pointing at a part, in the bar or the legend, picks it out; screen readers
|
|
313
|
+
hear every part's value and share from the bar's label. Sweeps in from
|
|
314
|
+
the start the first time it's seen. Colours default to the chart palette in
|
|
315
|
+
order, like DonutChart's.
|
|
316
|
+
|
|
317
|
+
| Prop | Type | Default | Description |
|
|
318
|
+
| --- | --- | --- | --- |
|
|
319
|
+
| `items` (required) | `AllocationItem[]` | | |
|
|
320
|
+
| `label` (required) | `string` | | What the whole is, e.g. "Income in September", for screen readers. |
|
|
321
|
+
| `className` | `string` | | |
|
|
322
|
+
| `formatValue` | `((value: number) => string)` | | |
|
|
323
|
+
| `legend` | `boolean` | `true` | The list of parts under the bar (default on). |
|
|
324
|
+
| `locale` | `string` | | For the shares' percent format. |
|
|
325
|
+
| `palette` | `ChartPalette` | `chart` | Colours for items that don't give their own: the categorical palette (default), or shades of the theme's glow. |
|