@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,69 @@
|
|
|
1
|
+
# Spinner
|
|
2
|
+
|
|
3
|
+
A small loading spinner in the current text colour, announced to screen readers when labelled.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { Spinner } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Default
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Spinner } from '@rinzai/zen';
|
|
15
|
+
|
|
16
|
+
/** Sized and coloured with className; it follows the text colour. */
|
|
17
|
+
export default function Default() {
|
|
18
|
+
return (
|
|
19
|
+
<div className="flex items-center gap-6">
|
|
20
|
+
<Spinner />
|
|
21
|
+
<Spinner className="size-6" />
|
|
22
|
+
<Spinner className="text-primary size-8 border-[3px]" />
|
|
23
|
+
<Spinner className="text-muted-foreground size-5" />
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Loading
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { Button, Card, CardHeader, CardTitle, Spinner } from '@rinzai/zen';
|
|
33
|
+
import { useState } from 'react';
|
|
34
|
+
|
|
35
|
+
/** Standing on its own, a spinner needs a label so screen readers announce what is loading. */
|
|
36
|
+
export default function Loading() {
|
|
37
|
+
const [loading, setLoading] = useState(true);
|
|
38
|
+
return (
|
|
39
|
+
<Card className="w-80">
|
|
40
|
+
<CardHeader>
|
|
41
|
+
<CardTitle>Entries</CardTitle>
|
|
42
|
+
</CardHeader>
|
|
43
|
+
{loading ? (
|
|
44
|
+
<div className="text-muted-foreground flex items-center gap-3 py-6 text-sm">
|
|
45
|
+
<Spinner label="Loading entries" />
|
|
46
|
+
Loading entries…
|
|
47
|
+
</div>
|
|
48
|
+
) : (
|
|
49
|
+
<p className="py-6 text-sm">12 entries this month.</p>
|
|
50
|
+
)}
|
|
51
|
+
<Button variant="outline" size="sm" onClick={() => setLoading((l) => !l)}>
|
|
52
|
+
{loading ? 'Finish loading' : 'Load again'}
|
|
53
|
+
</Button>
|
|
54
|
+
</Card>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## API reference
|
|
60
|
+
|
|
61
|
+
### Spinner
|
|
62
|
+
|
|
63
|
+
Small circular spinner in the current text colour; size it with className
|
|
64
|
+
(default size-4). Decorative by default (e.g. inside a loading Button). Give
|
|
65
|
+
it a `label` when it stands on its own, and screen readers announce it.
|
|
66
|
+
|
|
67
|
+
| Prop | Type | Default | Description |
|
|
68
|
+
| --- | --- | --- | --- |
|
|
69
|
+
| `label` | `string` | | What is loading, e.g. "Loading entries". Makes the spinner announce itself. |
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Status Pill
|
|
2
|
+
|
|
3
|
+
A small status that changes in place, such as Saving…, Saved or Not saved with a Retry, and fades back once the news is old.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { StatusPill, StatusPillAction } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Save
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Button, Spinner, StatusPill, StatusPillAction } from '@rinzai/zen';
|
|
15
|
+
import { useEffect, useState } from 'react';
|
|
16
|
+
// Icons from Heroicons (https://heroicons.com): AlertTriangle (exclamation-triangle), Check (check).
|
|
17
|
+
|
|
18
|
+
type Save = 'saving' | 'saved' | 'error';
|
|
19
|
+
|
|
20
|
+
/** A save indicator: saving spins, saved checks and then quietens, a failure is red and offers a retry. */
|
|
21
|
+
export default function Save() {
|
|
22
|
+
const [state, setState] = useState<Save>('saved');
|
|
23
|
+
const [quiet, setQuiet] = useState(false);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
setQuiet(false);
|
|
26
|
+
if (state !== 'saved') return;
|
|
27
|
+
const t = window.setTimeout(() => setQuiet(true), 2500);
|
|
28
|
+
return () => window.clearTimeout(t);
|
|
29
|
+
}, [state]);
|
|
30
|
+
const save = (ok: boolean) => {
|
|
31
|
+
setState('saving');
|
|
32
|
+
window.setTimeout(() => setState(ok ? 'saved' : 'error'), 1200);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div className="flex flex-col items-center gap-4">
|
|
37
|
+
{state === 'error' ? (
|
|
38
|
+
<StatusPill tone="negative">
|
|
39
|
+
<AlertTriangle />
|
|
40
|
+
Not saved
|
|
41
|
+
<StatusPillAction onClick={() => save(true)}>Retry</StatusPillAction>
|
|
42
|
+
</StatusPill>
|
|
43
|
+
) : (
|
|
44
|
+
<StatusPill tone={state === 'saved' ? 'positive' : 'default'} quiet={state === 'saved' && quiet}>
|
|
45
|
+
{state === 'saving' ? <Spinner /> : <Check />}
|
|
46
|
+
{state === 'saving' ? 'Saving…' : 'Saved'}
|
|
47
|
+
</StatusPill>
|
|
48
|
+
)}
|
|
49
|
+
<div className="flex gap-2">
|
|
50
|
+
<Button variant="outline" size="sm" onClick={() => save(true)}>
|
|
51
|
+
Save
|
|
52
|
+
</Button>
|
|
53
|
+
<Button variant="outline" size="sm" onClick={() => save(false)}>
|
|
54
|
+
Save and fail
|
|
55
|
+
</Button>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## API reference
|
|
63
|
+
|
|
64
|
+
### StatusPill
|
|
65
|
+
|
|
66
|
+
A small rounded status that changes in place, e.g. an app's "Saving…",
|
|
67
|
+
"Saved", "Not saved · Retry": an icon (a Spinner, a Check) and a few words.
|
|
68
|
+
`quiet` fades it back once the news is old (a save a few seconds ago).
|
|
69
|
+
Changes are read out politely (role="status"). For an action inside it,
|
|
70
|
+
such as Retry, use StatusPillAction. For a fixed label or count, use Badge.
|
|
71
|
+
|
|
72
|
+
| Prop | Type | Default | Description |
|
|
73
|
+
| --- | --- | --- | --- |
|
|
74
|
+
| `quiet` | `boolean` | `false` | Faded back into the page: the news is old. |
|
|
75
|
+
| `tone` | `"default" \| "negative" \| "positive"` | `default` | `positive` in the accent colour (done), `negative` in red (failed); `default` is muted (in progress). |
|
|
76
|
+
|
|
77
|
+
### StatusPillAction
|
|
78
|
+
|
|
79
|
+
A text button inside a StatusPill, e.g. Retry, in the pill's colour.
|
|
80
|
+
|
|
81
|
+
No props of its own; it accepts the props of the element it renders.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Stepper
|
|
2
|
+
|
|
3
|
+
The steps of a flow and where you are in it; the line between them fills in as you go.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { Stepper, Step } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Default
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Button, Step, Stepper } from '@rinzai/zen';
|
|
15
|
+
import { useState } from 'react';
|
|
16
|
+
|
|
17
|
+
/** Importing a statement in three steps. */
|
|
18
|
+
export default function Default() {
|
|
19
|
+
const [step, setStep] = useState(1);
|
|
20
|
+
return (
|
|
21
|
+
<div className="flex w-full max-w-lg flex-col items-center gap-8">
|
|
22
|
+
<Stepper value={step}>
|
|
23
|
+
<Step description="CSV or Excel">Upload</Step>
|
|
24
|
+
<Step description="Match the columns">Map</Step>
|
|
25
|
+
<Step description="Check and import">Review</Step>
|
|
26
|
+
</Stepper>
|
|
27
|
+
<div className="flex gap-2">
|
|
28
|
+
<Button variant="outline" disabled={step === 0} onClick={() => setStep(step - 1)}>
|
|
29
|
+
Back
|
|
30
|
+
</Button>
|
|
31
|
+
<Button disabled={step === 3} onClick={() => setStep(step + 1)}>
|
|
32
|
+
{step >= 2 ? 'Import' : 'Next'}
|
|
33
|
+
</Button>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API reference
|
|
41
|
+
|
|
42
|
+
### Stepper
|
|
43
|
+
|
|
44
|
+
The steps of a flow (sign-up, checkout, import), with where you are: steps
|
|
45
|
+
before `value` (from 0) are done, the one at it is current. The line between
|
|
46
|
+
them fills in as you go.
|
|
47
|
+
|
|
48
|
+
| Prop | Type | Default | Description |
|
|
49
|
+
| --- | --- | --- | --- |
|
|
50
|
+
| `value` (required) | `number` | | The current step, from 0. Steps before it are done; past the last, all are. |
|
|
51
|
+
|
|
52
|
+
### Step
|
|
53
|
+
|
|
54
|
+
One step's label, and optionally a line under it (`description`).
|
|
55
|
+
|
|
56
|
+
| Prop | Type | Default | Description |
|
|
57
|
+
| --- | --- | --- | --- |
|
|
58
|
+
| `className` | `string` | | |
|
|
59
|
+
| `description` | `ReactNode` | | |
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Tab Bar
|
|
2
|
+
|
|
3
|
+
Phone navigation fixed to the bottom of the screen. Works with any router.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { TabBar, TabBarItem } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Default
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { TabBar, TabBarItem } from '@rinzai/zen';
|
|
15
|
+
import { useState } from 'react';
|
|
16
|
+
// Icons from Heroicons (https://heroicons.com): CalendarIcon (calendar), Flag (flag), Settings (cog-6-tooth), TableIcon (table-cells).
|
|
17
|
+
|
|
18
|
+
const TABS = [
|
|
19
|
+
{ label: 'Month', icon: <CalendarIcon /> },
|
|
20
|
+
{ label: 'Planner', icon: <TableIcon /> },
|
|
21
|
+
{ label: 'Goals', icon: <Flag /> },
|
|
22
|
+
{ label: 'Settings', icon: <Settings /> },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/** Phone navigation. Fixed to the bottom of the screen; here it sits in a phone-sized frame. */
|
|
26
|
+
export default function Default() {
|
|
27
|
+
const [current, setCurrent] = useState('Month');
|
|
28
|
+
return (
|
|
29
|
+
<div className="border-tint/10 relative h-72 w-80 [transform:translateZ(0)] overflow-hidden rounded-2xl border">
|
|
30
|
+
<p className="text-muted-foreground p-4 text-sm">{current}</p>
|
|
31
|
+
<TabBar aria-label="Main" hideFrom={false} className="absolute! rounded-b-[15px]">
|
|
32
|
+
{TABS.map((t) => (
|
|
33
|
+
<TabBarItem
|
|
34
|
+
key={t.label}
|
|
35
|
+
href={`#${t.label.toLowerCase()}`}
|
|
36
|
+
icon={t.icon}
|
|
37
|
+
active={t.label === current}
|
|
38
|
+
onClick={(e) => {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
setCurrent(t.label);
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
{t.label}
|
|
44
|
+
</TabBarItem>
|
|
45
|
+
))}
|
|
46
|
+
</TabBar>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## API reference
|
|
53
|
+
|
|
54
|
+
### TabBar
|
|
55
|
+
|
|
56
|
+
Phone navigation: a glass bar fixed to the bottom, clear of the home
|
|
57
|
+
indicator, hidden from `hideFrom` up (default md). Fill it with TabBarItems.
|
|
58
|
+
Its height is kept in `--zen-tab-bar-height` on its parent (0px while
|
|
59
|
+
hidden): a PlayerBar beside it sits on it, and the page can pad its end by it.
|
|
60
|
+
Inside a rounded frame, round the bar to match (className, e.g.
|
|
61
|
+
rounded-b-[15px]): with GPU compositing, Chrome doesn't clip a blurred
|
|
62
|
+
backdrop to an ancestor's rounded corners, only to the element's own.
|
|
63
|
+
|
|
64
|
+
| Prop | Type | Default | Description |
|
|
65
|
+
| --- | --- | --- | --- |
|
|
66
|
+
| `hideFrom` | `"lg" \| "md" \| "sm" \| false` | `md` | Hide the bar from this breakpoint up (false: always show). |
|
|
67
|
+
|
|
68
|
+
### TabBarItem
|
|
69
|
+
|
|
70
|
+
One destination: an icon over a label. `active` marks the current page; with
|
|
71
|
+
`asChild`, the styles go onto your own link (e.g. a router's NavLink, which
|
|
72
|
+
sets aria-current itself).
|
|
73
|
+
|
|
74
|
+
| Prop | Type | Default | Description |
|
|
75
|
+
| --- | --- | --- | --- |
|
|
76
|
+
| `active` | `boolean` | | |
|
|
77
|
+
| `asChild` | `boolean` | | Style the single child element (a router link holding the label) instead of rendering an <a>; `icon` goes inside it. |
|
|
78
|
+
| `icon` | `ReactNode` | | |
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Table of Contents
|
|
2
|
+
|
|
3
|
+
An "On this page" list that highlights the section being read.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { TableOfContents } from '@rinzai/zen';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Examples
|
|
10
|
+
|
|
11
|
+
### Default
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { TableOfContents } from '@rinzai/zen';
|
|
15
|
+
|
|
16
|
+
/** Point items at heading ids; the link for the section being read lights up as you scroll. */
|
|
17
|
+
export default function Default() {
|
|
18
|
+
return (
|
|
19
|
+
<TableOfContents
|
|
20
|
+
className="w-48"
|
|
21
|
+
items={[
|
|
22
|
+
{ id: 'installation', label: 'Installation' },
|
|
23
|
+
{ id: 'usage', label: 'Usage' },
|
|
24
|
+
{ id: 'theming', label: 'Theming' },
|
|
25
|
+
{ id: 'tokens', label: 'Tokens', depth: 2 },
|
|
26
|
+
]}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## API reference
|
|
33
|
+
|
|
34
|
+
### TableOfContents
|
|
35
|
+
|
|
36
|
+
"On this page": links to the page's headings, highlighting the section being
|
|
37
|
+
read. Items point at element ids; nested items (depth 2) are indented.
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Description |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| `items` (required) | `TableOfContentsItem[]` | | |
|
|
42
|
+
| `className` | `string` | | |
|
|
43
|
+
| `title` | `string` | | Shown above the list, and names it. Empty: no heading shown (e.g. under a trigger that says it). |
|