@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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Added to existing components
|
|
6
|
+
|
|
7
|
+
- **MenuContent**: `sheet` makes the menu a bottom sheet on phones (below `md`), as music apps show a song's menu: across the bottom of the screen over a scrim, with a grip, swiped down or tapped outside to close. Its submenus slide in over it, with a row at the top that goes back (the arrow back and Escape still do), and open only when chosen, not on hover. Wider screens keep the popover.
|
|
8
|
+
- **SortableList**: works with a virtualized list. Give it `itemHeight` and render only the rows in view (from `useVirtualList`), each at its place in `value`; a drag works from `value`, not the rows on screen, and rows that come into view as it scrolls the list take their places. `onLiftedChange` says which item is picked up (by its handle or from the keyboard), to keep its row rendered. An item moved with the keyboard is scrolled into view.
|
|
9
|
+
- **useVirtualList**: `keep` renders a row even when it's out of view, such as the one being dragged, with the rows between.
|
|
10
|
+
- **SeekBar**: `times="below"` puts the time played and the length under the ends of the bar, as on a phone's Now Playing screen.
|
|
11
|
+
- **TooltipContent**: `side="beside"` puts the tooltip after its trigger (before it if there's no room) instead of below, centred on it, as for the icons of a collapsed sidebar, where a tooltip below would cover the next icon. `align` lines up its top or bottom with the trigger's instead.
|
|
12
|
+
- **Anchored popups** (`anchoredStyle`): beside the trigger, `align` now chooses top (start, as before), middle (center) or bottom (end).
|
|
13
|
+
|
|
14
|
+
### Fixes
|
|
15
|
+
|
|
16
|
+
- **ToastProvider**: once its toasts were gone, the empty toast area kept its last height (the height it was given went negative, which browsers ignore) and caught clicks meant for what was under it, such as a player bar's controls. It now shrinks to nothing.
|
|
17
|
+
|
|
18
|
+
## 0.15.0
|
|
19
|
+
|
|
20
|
+
### New components
|
|
21
|
+
|
|
22
|
+
- **PlayerBar**: what's playing, in a glass bar along the bottom of the screen, laid out as you like. On phones it sits on the TabBar beside it.
|
|
23
|
+
- **SeekBar**: where playback is, filled to the time played and shaded on to what's loaded, between the time played and the length. Pass `playing` and it glides between the player's time updates, moved by the browser's compositor rather than per-frame renders. Dragging doesn't interrupt playback; letting go seeks; the arrow keys seek 5 seconds.
|
|
24
|
+
- **Marquee**: one line of text cut off with an ellipsis that scrolls to show the rest: on hover or keyboard focus of itself or of its `data-zen-marquee-host` (a row, a tile), or always (`trigger="always"`, for what's playing). Only text that doesn't fit moves, at the same speed whatever its length, with fades at the edges. Stays an ellipsis for reduced motion; the accessible name is the text.
|
|
25
|
+
- **useMediaPlayer**: drives your own `<audio>` or `<video>` (`const [ref, player] = useMediaPlayer()`, then `<audio ref={ref} />`) and keeps its state: playing, waiting, time, duration, buffered, volume. With `play`, `pause`, `toggle`, `seek`, `setVolume` and `setMuted`.
|
|
26
|
+
- **useMediaSession**: puts what's playing on the lock screen and the OS media controls (title, artist, cover, position), and lets play, pause, seek, previous, next and the media keys control your player.
|
|
27
|
+
- **formatDuration**: seconds as a clock reads them (3:07, 1:02:07).
|
|
28
|
+
|
|
29
|
+
### Renamed
|
|
30
|
+
|
|
31
|
+
- **TextArea** is now **Textarea** (and `TextAreaProps` is `TextareaProps`), like the element. The old names still work, marked deprecated, until the next breaking release.
|
|
32
|
+
|
|
33
|
+
### Added to existing components
|
|
34
|
+
|
|
35
|
+
- **TabBar**: its height is kept in `--zen-tab-bar-height` on its parent (0px while hidden), for a PlayerBar to sit on and the page to pad its end by. PlayerBar keeps `--zen-player-bar-height` the same way.
|
|
36
|
+
- **Segmented**, **RadioCards**: `label` is optional. Without it, name the group with `aria-label` or `aria-labelledby`, as on RadioGroup.
|
|
37
|
+
- **Slider**: `step="any"` for no snapping.
|
|
38
|
+
|
|
39
|
+
### Fixes
|
|
40
|
+
|
|
41
|
+
- **SegmentedItem**: an icon and its text sit side by side; they stacked.
|
|
42
|
+
- **Popover, Menu, Select and every anchored popup**: with no room below the trigger, a centred popup wider than its trigger stayed below it, off screen (Chrome) or over the trigger (Firefox), instead of flipping above. It flips now, and a popup lined up with an edge also switches edges when there's no room beside it.
|
|
43
|
+
- **Carousel**: where the slides don't fill the view evenly, Next stopped short of the end, the last slide cut off. The end is now the last stop, with its own dot.
|
|
44
|
+
- **TabBarItem**, **MenuItem**: with `asChild`, `icon` was dropped; it now goes ahead of your link's content, also when that content is a render function (a NavLink's).
|
|
45
|
+
|
|
46
|
+
### Docs
|
|
47
|
+
|
|
48
|
+
- The docs ship in the package as markdown, for AI agents: `node_modules/@rinzai/zen/dist/docs` has a page per component with every example's source, and the CHANGELOG is included. The site serves the same pages at `/docs/<component>.md`, with `/llms.txt` and `/llms-full.txt`.
|
|
49
|
+
- Props tables cover parts kept outside a package's `index.tsx`, such as SortableTree, SortableItem, DonutChart and the table's selection and swipe parts.
|
|
50
|
+
- The package's markdown pages have the props tables too, the same as the site's. Their README and `llms.txt` carry the README's guide: setup, the props every component takes, values and forms, languages, theming, overlays and browser support. The README now says Zen exports no icons.
|
|
51
|
+
|
|
52
|
+
## 0.14.0
|
|
53
|
+
|
|
54
|
+
### Added to existing components
|
|
55
|
+
|
|
56
|
+
- **NumberField**: `onValueChange` gets a second argument saying how the number changed: `{ reason: 'step', delta }` for − +, ↑↓ and Page Up/Down, `'input'` for typing, `'limit'` for Home and End. `onValueCommit` fires once per finished change: each step, and what's typed on Enter or on leaving the field. So a step can be sent on as a step to whatever keeps the number (see Number Field → Steps).
|
|
57
|
+
|
|
58
|
+
## 0.13.0
|
|
59
|
+
|
|
60
|
+
Since 0.12.0. This release renames things. Every breaking change is listed first, with what to change.
|
|
61
|
+
|
|
62
|
+
### Breaking changes
|
|
63
|
+
|
|
64
|
+
#### Callbacks are named for what they change
|
|
65
|
+
|
|
66
|
+
| Before | After |
|
|
67
|
+
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
68
|
+
| `onChange` | `onValueChange` on Select, Segmented, RadioGroup, RadioCards, Calendar, DatePicker, DateRangePicker, MonthPicker, MoneyInput, ColorPicker, ColorPanel, IconPicker, RepeatPicker and SortableList (Combobox, Keypad, Slider, RangeSlider, TagInput and Tabs already used it) |
|
|
69
|
+
| `onChange(checked)` on Checkbox, Toggle | `onCheckedChange(checked)`; `onChange` is the native event again |
|
|
70
|
+
| Canvas `onChange` / `onChangeEnd` / `onSelect` | `onItemsChange` / `onItemsChangeEnd` / `onSelectedChange` |
|
|
71
|
+
| CalendarHeatmap `onSelect` | `onSelectedChange` |
|
|
72
|
+
| DatePicker, DateRangePicker, MonthPicker `onClear` | `clearable`; clearing calls `onValueChange(null)` |
|
|
73
|
+
|
|
74
|
+
`value` is optional wherever it was required. Leave it out and pass `defaultValue` to let the control keep its own.
|
|
75
|
+
|
|
76
|
+
#### One tone scale: `default`, `positive`, `negative`
|
|
77
|
+
|
|
78
|
+
| Before | After |
|
|
79
|
+
| --------------------------------------------------------------- | ------------------------------------------ |
|
|
80
|
+
| `destructive` (Button, Badge, ChartReference, TableSwipeAction) | `tone="negative"` |
|
|
81
|
+
| `danger` (Meter), `error` (Toast, FormMessage) | `negative` |
|
|
82
|
+
| `success` | `positive` |
|
|
83
|
+
| `info` (Toast, FormMessage), `primary` (Sparkline) | `default` |
|
|
84
|
+
| MenuItem, ConfirmDialog `destructive` | `tone="negative"` |
|
|
85
|
+
| Button `variant="destructive"` | `tone="negative"` (on the default variant) |
|
|
86
|
+
| Button `variant="icon"` | `variant="ghost"` with an icon size |
|
|
87
|
+
|
|
88
|
+
#### Sizes
|
|
89
|
+
|
|
90
|
+
- Icon buttons line up with fields and buttons of the same size: `icon-sm` is 32px, `icon` is 40px (was 36), `icon-lg` is 44px. The old 24px `icon-sm` is now `icon-xs`.
|
|
91
|
+
- ThemeToggle is 40px.
|
|
92
|
+
- Input's `size` is `"sm" | "lg"` (Button's heights). It no longer passes through the native `size` attribute.
|
|
93
|
+
|
|
94
|
+
#### Right to left
|
|
95
|
+
|
|
96
|
+
- Table: `sticky="left"` is `sticky="start"`.
|
|
97
|
+
- TableContainer's `data-under-left` attribute is `data-under-start`.
|
|
98
|
+
- The `.zen__sticky-left` class is `.zen__sticky-start`.
|
|
99
|
+
- Spacing, corners and positions use logical sides, so a class you override may now be `ps-*`/`pe-*`/`start-*`/`end-*`/`text-start` rather than `pl-*`/`left-*`/`text-left`.
|
|
100
|
+
|
|
101
|
+
#### Forms
|
|
102
|
+
|
|
103
|
+
- MoneyInput with `name` submits the amount in minor units, from a hidden input (e.g. `123450` for $1,234.50). It used to submit the visible text.
|
|
104
|
+
|
|
105
|
+
#### Words
|
|
106
|
+
|
|
107
|
+
- `ICON_COLORS` entries no longer have English labels: `IconColor.label` is optional, and the names come from the messages.
|
|
108
|
+
- `ImageCropError` takes a `reason` code first, `new ImageCropError(reason, message)`, so you can show the error in your own words.
|
|
109
|
+
- `describeRepeat` takes the words as an optional last argument.
|
|
110
|
+
|
|
111
|
+
### New components
|
|
112
|
+
|
|
113
|
+
- **Accordion**: disclosures where one or several (`multiple`) open at a time, with ↑↓, Home and End between headings.
|
|
114
|
+
- **Separator**: across or upright, and `decorative` when it's only visual.
|
|
115
|
+
- **ToggleGroup**: buttons that stay pressed, one or several (`multiple`).
|
|
116
|
+
- **Toolbar**: one Tab stop, with arrow keys through its controls, a ToggleGroup's items included. Runs across or upright.
|
|
117
|
+
- **ButtonGroup**: buttons joined into one control, a split button's menu included.
|
|
118
|
+
- **HoverCard**: a glass preview of what a link points to, on hover or keyboard focus.
|
|
119
|
+
- **NumberField**: a number with − and + buttons and arrow keys (PageUp/PageDown for larger steps). Typed and shown in the locale's format, including percent.
|
|
120
|
+
- **TimeField**: hours, minutes and AM/PM as segments, in the locale's order and clock.
|
|
121
|
+
- **Carousel**: native scroll snapping, with glass previous/next buttons and dots in CarouselControls, and the arrow keys.
|
|
122
|
+
- **Resizable** (ResizablePanelGroup, ResizablePanel, ResizableHandle): drag a handle or use the arrow keys, within each panel's limits. Groups nest, and `onLayout` reports the sizes.
|
|
123
|
+
- **Menubar**: a row of menus with one Tab stop. ←→ move between them; with one open, ←→ open the next and hover switches.
|
|
124
|
+
- **NavigationMenu**: site navigation with panels of links that open on hover or click.
|
|
125
|
+
- **SortableTree**: drag-and-drop for groups and nested items. Drop into another group, into an open sub-item, or under another item; `accepts` says what goes where. Keyboard: ↑↓ through every allowed place, ←→ a level out or in, each step announced. Works on table rows (see Table → Reorder).
|
|
126
|
+
- **LocaleProvider**: the locale and every word Zen shows or announces. Pass a partial `messages` to translate or reword any of them (`ENGLISH` lists them all).
|
|
127
|
+
|
|
128
|
+
### Added to existing components
|
|
129
|
+
|
|
130
|
+
- **Menu**:
|
|
131
|
+
- Submenus (MenuSub, MenuSubTrigger, MenuSubContent).
|
|
132
|
+
- MenuCheckboxItem, and MenuRadioGroup with MenuRadioItem.
|
|
133
|
+
- ↓ or ↑ on a MenuTrigger opens the menu at its first or last item.
|
|
134
|
+
- **SortableList**: `asChild` on the list and its items, to sort your own elements, such as a TableBody's rows.
|
|
135
|
+
- **Fields** (Input, InputGroup, MoneyInput, Select, Combobox, DatePicker, DateRangePicker, MonthPicker, ColorPicker): `size="sm" | "lg"`, at Button's heights.
|
|
136
|
+
- **Form submission and reset**: custom controls with a `name` are submitted with their form and reset with it. These are Combobox, the date and month pickers, MoneyInput, ColorPicker, TagInput, RepeatPicker, RangeSlider and IconPicker.
|
|
137
|
+
- **Props and refs**: `id`, `data-*`, `aria-*`, `style`, handlers and `ref` reach every component's element. Where a component keeps its own ref, yours is merged with it.
|
|
138
|
+
- **Exported props types**: every component's props type is exported (`ButtonProps`, `TabsProps`…).
|
|
139
|
+
- **Server components**: `'use client'` marks only modules that use React. Money, dates, `cx`, colours and the package entry can be called from server components.
|
|
140
|
+
- **Right to left**: layout, arrow keys, chevrons and slider fills follow `dir`. Calendar, CalendarHeatmap and Pagination use the locale's digits.
|
|
141
|
+
- **Focus**: every control uses the same keyboard focus ring (the `focus-ring` utility).
|
|
142
|
+
|
|
143
|
+
### Fixes
|
|
144
|
+
|
|
145
|
+
- Calendar marks today only once hydrated, so server and client render the same.
|
|
146
|
+
- Combobox's list is named after its field.
|
|
147
|
+
- Tabs without panels no longer point `aria-controls` at nothing.
|
|
148
|
+
- Closed popovers and dialogs stay hidden whatever `className` lays them out with.
|
|
149
|
+
- HoverCard and Tooltip are placed against their trigger in browsers without CSS anchor positioning.
|
|
150
|
+
|
|
151
|
+
### Tests
|
|
152
|
+
|
|
153
|
+
- Behaviour tests now run in Chromium, Firefox and WebKit, with new keyboard tests and accessibility checks of open popups in both themes. CI runs them.
|
package/README.md
CHANGED
|
@@ -57,18 +57,33 @@ export default function App() {
|
|
|
57
57
|
}
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
## For AI agents
|
|
61
|
+
|
|
62
|
+
Every docs page ships with the package as markdown, matching the installed version: `node_modules/@rinzai/zen/dist/docs` (README.md lists them), with the CHANGELOG at the package root. Point your agent there from your `AGENTS.md` or `CLAUDE.md`:
|
|
63
|
+
|
|
64
|
+
```md
|
|
65
|
+
UI components come from @rinzai/zen. Its docs, with every example's source, are in node_modules/@rinzai/zen/dist/docs; start at README.md there.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The site has them too: [llms.txt](https://zen.rinzai.dev/llms.txt), [llms-full.txt](https://zen.rinzai.dev/llms-full.txt) (everything in one file) and `/docs/<component>.md`.
|
|
69
|
+
|
|
60
70
|
## What's inside
|
|
61
71
|
|
|
62
72
|
- **Surfaces:** Card, Inset, Alert, Stat, Dialog (and sheets from an edge), ConfirmDialog, Popover, Tooltip, HoverCard, Toast (a stacked deck), Disclosure, Accordion, Separator, Resizable panels, Carousel, Backdrop (aurora, contours or dots, and a pointer light)
|
|
63
|
-
- **Inputs:** Button, ButtonGroup, Toggle, ToggleGroup, Toolbar, Input,
|
|
73
|
+
- **Inputs:** Button, ButtonGroup, Toggle, ToggleGroup, Toolbar, Input, Textarea, InputGroup, NumberField, TimeField, MoneyInput (with currency conversion), Select, Combobox, Calendar, DatePicker, DateRangePicker, MonthPicker, ColorPicker, Checkbox, RadioGroup, RadioCards, Segmented, Slider, Chip, Field
|
|
64
74
|
- **Data:** Chart (areas, lines, bars) and DonutChart in plain SVG, composable Table with sticky edges, sorting and rows reordered by drag and drop, tree rows, editable cells, virtual rows, SortableList and SortableTree, Meter, ProgressRing, AnimatedNumber, Badge, StatusPill (a live save status), Skeleton, Spinner, Canvas (items placed freely, with snapping)
|
|
65
75
|
- **Navigation:** Header, NavigationMenu, Pills, Tabs, TabBar, SideNav, TableOfContents, Menu (with submenus, checkbox and radio items, and context menus), Menubar
|
|
76
|
+
- **Media:** PlayerBar (sits on a TabBar), SeekBar, Marquee (cut-off titles that scroll to show the rest), `useMediaPlayer` for your own `<audio>` or `<video>`, `useMediaSession` for the lock screen and media keys, `formatDuration`
|
|
66
77
|
- **Theming:** dark and light, OKLCH tokens, and a theme generator (presets or any hue) that keeps contrast readable
|
|
67
78
|
- **Languages:** LocaleProvider for the locale and every word, and right-to-left layout
|
|
68
79
|
- **Hooks and utilities:** `themeWave` (the theme spreads from the switch like a drop falling into water: ripples, glints and a rainbow edge, drawn on the GPU; `prepareThemeWave` readies it when the pointer reaches your own switch), `useAnchoredPopup`, `useVirtualList`, `useTree`, `useSort`, `useCopyToClipboard`, money, currency, month and date helpers, `hexToOklch` and `oklchToHex`, `cx` (Tailwind-aware class merging), `cva`
|
|
69
80
|
|
|
81
|
+
## Props
|
|
82
|
+
|
|
70
83
|
Every component takes `className`, and a class you pass always overrides the component's default. Other props (`id`, `aria-*`, `data-*`, handlers) and `ref` reach its element, and parts that render a link or button take `asChild` to use your own (a router's Link, say).
|
|
71
84
|
|
|
85
|
+
Zen exports no icons. Use any icon set (the examples use [Heroicons](https://heroicons.com)) and pass icons in as elements, such as `icon={<HomeIcon />}`.
|
|
86
|
+
|
|
72
87
|
## Values and forms
|
|
73
88
|
|
|
74
89
|
Controls report changes with `onValueChange` (`onCheckedChange` for Checkbox and Toggle). Pass `value` to control one, or `defaultValue` to let it keep its own. Give a control a `name` and it's submitted with its form, the custom ones (Combobox, the date pickers, MoneyInput, ColorPicker, TagInput…) included, and goes back to its first value when the form is reset.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useLocale as e } from "../locale-provider/index.js";
|
|
3
|
+
import { cx as t } from "../utils/cx.js";
|
|
4
4
|
import { formatMoney as n } from "../utils/money.js";
|
|
5
5
|
import { reducedMotion as r } from "../utils/motion.js";
|
|
6
6
|
import { useEffect as i, useLayoutEffect as a, useRef as o, useState as s } from "react";
|
|
7
7
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
8
8
|
//#region packages/animated-number/index.tsx
|
|
9
9
|
var u = typeof window > "u" ? i : a, d = (e) => 1 - (1 - e) ** 3;
|
|
10
|
-
function f({ value:
|
|
11
|
-
let [g, _] = s(f ? 0 :
|
|
10
|
+
function f({ value: e, format: n = String, duration: a = 650, fromZero: f = !0, roll: p = !1, className: h }) {
|
|
11
|
+
let [g, _] = s(f ? 0 : e), v = o(f ? 0 : e), [y, b] = s(!f);
|
|
12
12
|
if (i(() => {
|
|
13
13
|
if (!p || y) return;
|
|
14
14
|
let e = requestAnimationFrame(() => b(!0));
|
|
@@ -16,22 +16,22 @@ function f({ value: t, format: n = String, duration: a = 650, fromZero: f = !0,
|
|
|
16
16
|
}, [p, y]), u(() => {
|
|
17
17
|
if (p) return;
|
|
18
18
|
if (r() || a <= 0) {
|
|
19
|
-
v.current =
|
|
19
|
+
v.current = e, _(e);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
let
|
|
23
|
-
let s = Math.min(1, (o - n) / a), c = Math.round(
|
|
22
|
+
let t = v.current, n = performance.now(), i = requestAnimationFrame(function r(o) {
|
|
23
|
+
let s = Math.min(1, (o - n) / a), c = Math.round(t + (e - t) * d(s));
|
|
24
24
|
v.current = c, _(c), s < 1 && (i = requestAnimationFrame(r));
|
|
25
25
|
});
|
|
26
26
|
return () => cancelAnimationFrame(i);
|
|
27
27
|
}, [
|
|
28
|
-
|
|
28
|
+
e,
|
|
29
29
|
a,
|
|
30
30
|
p
|
|
31
31
|
]), p) {
|
|
32
|
-
let r = n(
|
|
32
|
+
let r = n(e);
|
|
33
33
|
return /* @__PURE__ */ l("span", {
|
|
34
|
-
className:
|
|
34
|
+
className: t("zen__animated-number inline-flex items-start tabular-nums", h),
|
|
35
35
|
children: [/* @__PURE__ */ c("span", {
|
|
36
36
|
className: "sr-only",
|
|
37
37
|
children: r
|
|
@@ -46,7 +46,7 @@ function f({ value: t, format: n = String, duration: a = 650, fromZero: f = !0,
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
return /* @__PURE__ */ c("span", {
|
|
49
|
-
className:
|
|
49
|
+
className: t("zen__animated-number tabular-nums", h),
|
|
50
50
|
children: n(g)
|
|
51
51
|
});
|
|
52
52
|
}
|
|
@@ -75,10 +75,10 @@ function m({ digit: e, duration: t }) {
|
|
|
75
75
|
})
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
|
-
function h({ value:
|
|
79
|
-
let s =
|
|
78
|
+
function h({ value: t, currency: r, locale: i, showDecimals: a = !1, ...o }) {
|
|
79
|
+
let s = e(i);
|
|
80
80
|
return /* @__PURE__ */ c(f, {
|
|
81
|
-
value:
|
|
81
|
+
value: t,
|
|
82
82
|
format: (e) => n(e, r, s, { showDecimals: a }),
|
|
83
83
|
...o
|
|
84
84
|
});
|
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import e from "../
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { useMessages as e } from "../locale-provider/index.js";
|
|
3
|
+
import t from "../icons/micro/chevron-right.js";
|
|
4
|
+
import { cx as n } from "../utils/cx.js";
|
|
5
|
+
import { Slot as r } from "../utils/slot.js";
|
|
6
6
|
import { Children as i, Fragment as a, isValidElement as o } from "react";
|
|
7
7
|
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
8
8
|
//#region packages/breadcrumbs/index.tsx
|
|
9
|
-
function l({ className:
|
|
10
|
-
let f =
|
|
9
|
+
function l({ className: r, children: l, "aria-label": u, ...d }) {
|
|
10
|
+
let f = e(), p = u ?? f.breadcrumb, m = i.toArray(l).filter(o);
|
|
11
11
|
return /* @__PURE__ */ s("nav", {
|
|
12
12
|
"aria-label": p,
|
|
13
|
-
className:
|
|
13
|
+
className: n("zen__breadcrumbs", r),
|
|
14
14
|
...d,
|
|
15
15
|
children: /* @__PURE__ */ s("ol", {
|
|
16
16
|
className: "text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm",
|
|
17
|
-
children: m.map((
|
|
17
|
+
children: m.map((e, n) => /* @__PURE__ */ c(a, { children: [n > 0 && /* @__PURE__ */ s("li", {
|
|
18
18
|
"aria-hidden": !0,
|
|
19
19
|
className: "text-muted-foreground/60 flex",
|
|
20
|
-
children: /* @__PURE__ */ s(
|
|
20
|
+
children: /* @__PURE__ */ s(t, { className: "size-3.5 rtl:-scale-x-100" })
|
|
21
21
|
}), /* @__PURE__ */ s("li", {
|
|
22
22
|
className: "flex min-w-0",
|
|
23
|
-
children:
|
|
24
|
-
})] },
|
|
23
|
+
children: e
|
|
24
|
+
})] }, e.key ?? n))
|
|
25
25
|
})
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
-
function u({ current: e, asChild:
|
|
29
|
-
let o =
|
|
28
|
+
function u({ current: e, asChild: t, className: i, ...a }) {
|
|
29
|
+
let o = n("truncate rounded-sm outline-hidden transition-colors focus-ring", e ? "text-foreground font-medium" : "hover:text-foreground touch-target", i);
|
|
30
30
|
return e ? /* @__PURE__ */ s("span", {
|
|
31
31
|
"aria-current": "page",
|
|
32
32
|
className: o,
|
|
33
33
|
...a
|
|
34
|
-
}) : s(
|
|
34
|
+
}) : s(t ? r : "a", {
|
|
35
35
|
className: o,
|
|
36
36
|
...a
|
|
37
37
|
});
|
package/dist/calendar/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { useLocale as e, useMessages as t } from "../locale-provider/index.js";
|
|
3
|
+
import { cx as n } from "../utils/cx.js";
|
|
4
|
+
import { readingKey as r } from "../utils/direction.js";
|
|
5
|
+
import { useControllable as i } from "../utils/useControllable.js";
|
|
6
6
|
import { PICKER_MONTH as a, PICKER_NAV as o } from "../utils/styles.js";
|
|
7
7
|
import s from "../icons/chevron-left.js";
|
|
8
8
|
import c from "../icons/chevron-right.js";
|
|
@@ -13,7 +13,7 @@ import { useEffect as ae, useId as oe, useRef as _, useState as v } from "react"
|
|
|
13
13
|
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
14
14
|
//#region packages/calendar/index.tsx
|
|
15
15
|
function se(se) {
|
|
16
|
-
let { locale: le, min: x, max: S, isDisabled: ue, weekStartsOn: de, months: C = 1, defaultMonth: fe, className: w, autoFocus: pe, mode: T, value: me, defaultValue: he = null, onValueChange: ge, ...E } = se, D =
|
|
16
|
+
let { locale: le, min: x, max: S, isDisabled: ue, weekStartsOn: de, months: C = 1, defaultMonth: fe, className: w, autoFocus: pe, mode: T, value: me, defaultValue: he = null, onValueChange: ge, ...E } = se, D = e(le), _e = new Intl.NumberFormat(D), O = t(), k = de ?? re(D), [A, j] = i(me, he, ge), M = T === "range" ? A : null, N = T === "range" ? null : A, P = N ?? M?.start ?? null, F = ne(), I = ie() ? F : null, [L, R] = v(() => fe ?? (P ?? F).slice(0, 7)), [z, B] = v(() => P ?? F), [V, H] = v(null), [U, W] = v("days"), [G, K] = v(() => Number(L.slice(0, 4))), q = _(null), J = _(pe ?? !1), ve = oe(), ye = l(L, C - 1), be = (e) => e.slice(0, 7) >= L && e.slice(0, 7) <= ye, xe = (e) => !!x && e < x || !!S && e > S || !!ue?.(e), Y = be(z) ? z : m(z, f(z.slice(0, 7), L));
|
|
17
17
|
ae(() => {
|
|
18
18
|
J.current && (J.current = !1, q.current?.querySelector(`[data-date="${Y}"]`)?.focus());
|
|
19
19
|
}, [Y, U]);
|
|
@@ -36,16 +36,16 @@ function se(se) {
|
|
|
36
36
|
} else j(e);
|
|
37
37
|
}
|
|
38
38
|
}, we = (e) => {
|
|
39
|
-
let
|
|
40
|
-
ArrowLeft: p(
|
|
41
|
-
ArrowRight: p(
|
|
42
|
-
ArrowUp: p(
|
|
43
|
-
ArrowDown: p(
|
|
44
|
-
Home: p(
|
|
45
|
-
End: p(
|
|
46
|
-
PageUp: m(
|
|
47
|
-
PageDown: m(
|
|
48
|
-
}[
|
|
39
|
+
let t = Y, n = (h(t) - k + 7) % 7, i = {
|
|
40
|
+
ArrowLeft: p(t, -1),
|
|
41
|
+
ArrowRight: p(t, 1),
|
|
42
|
+
ArrowUp: p(t, -7),
|
|
43
|
+
ArrowDown: p(t, 7),
|
|
44
|
+
Home: p(t, -n),
|
|
45
|
+
End: p(t, 6 - n),
|
|
46
|
+
PageUp: m(t, e.shiftKey ? -12 : -1),
|
|
47
|
+
PageDown: m(t, e.shiftKey ? 12 : 1)
|
|
48
|
+
}[r(e.key, e.currentTarget)];
|
|
49
49
|
i && (e.preventDefault(), Se(i));
|
|
50
50
|
}, X = M && M.end === null ? M.start : null, Te = X && V ? V < X ? [V, X] : [X, V] : null, [Z, Q] = M?.end ? [M.start, M.end] : Te ?? [null, null], Ee = (e) => {
|
|
51
51
|
R((t) => l(t, e));
|
|
@@ -80,16 +80,16 @@ function se(se) {
|
|
|
80
80
|
]
|
|
81
81
|
});
|
|
82
82
|
if (U === "months") {
|
|
83
|
-
let
|
|
83
|
+
let e = d(D);
|
|
84
84
|
return /* @__PURE__ */ b("div", {
|
|
85
|
-
className:
|
|
85
|
+
className: n("zen__calendar w-fit", w),
|
|
86
86
|
...E,
|
|
87
87
|
children: [$, /* @__PURE__ */ y("div", {
|
|
88
88
|
className: "grid w-64 grid-cols-3 gap-1",
|
|
89
89
|
role: "group",
|
|
90
90
|
"aria-labelledby": ve,
|
|
91
|
-
children:
|
|
92
|
-
let r = `${G}-${String(
|
|
91
|
+
children: e.map((e, t) => {
|
|
92
|
+
let r = `${G}-${String(t + 1).padStart(2, "0")}`, i = !!x && r < x.slice(0, 7) || !!S && r > S.slice(0, 7);
|
|
93
93
|
return /* @__PURE__ */ y("button", {
|
|
94
94
|
type: "button",
|
|
95
95
|
disabled: i,
|
|
@@ -98,8 +98,8 @@ function se(se) {
|
|
|
98
98
|
onClick: () => {
|
|
99
99
|
R(r), J.current = !0, B(m(z, f(z.slice(0, 7), r))), W("days");
|
|
100
100
|
},
|
|
101
|
-
className:
|
|
102
|
-
children:
|
|
101
|
+
className: n(a, r === L && "bg-primary text-primary-foreground hover:bg-primary"),
|
|
102
|
+
children: e
|
|
103
103
|
}, r);
|
|
104
104
|
})
|
|
105
105
|
})]
|
|
@@ -107,15 +107,15 @@ function se(se) {
|
|
|
107
107
|
}
|
|
108
108
|
let De = g(D, "narrow"), Oe = g(D, "long"), ke = Array.from({ length: 7 }, (e, t) => (k + t) % 7);
|
|
109
109
|
return /* @__PURE__ */ b("div", {
|
|
110
|
-
className:
|
|
110
|
+
className: n("zen__calendar w-fit", w),
|
|
111
111
|
...E,
|
|
112
112
|
children: [$, /* @__PURE__ */ y("div", {
|
|
113
113
|
ref: q,
|
|
114
114
|
className: "flex gap-4",
|
|
115
115
|
onKeyDown: we,
|
|
116
116
|
onMouseLeave: () => H(null),
|
|
117
|
-
children: Array.from({ length: C }, (
|
|
118
|
-
let r = l(L,
|
|
117
|
+
children: Array.from({ length: C }, (e, t) => {
|
|
118
|
+
let r = l(L, t), i = `${r}-01`, a = `${r}-${ee(r)}`, o = p(i, -((h(i) - k + 7) % 7));
|
|
119
119
|
return /* @__PURE__ */ b("table", {
|
|
120
120
|
role: "grid",
|
|
121
121
|
"aria-label": u(r, D, "long"),
|
|
@@ -131,14 +131,14 @@ function se(se) {
|
|
|
131
131
|
className: "text-muted-foreground size-9 text-xs font-medium",
|
|
132
132
|
children: De[e]
|
|
133
133
|
}, e)) }) }),
|
|
134
|
-
/* @__PURE__ */ y("tbody", { children: Array.from({ length: 6 }, (
|
|
135
|
-
let c = p(o,
|
|
134
|
+
/* @__PURE__ */ y("tbody", { children: Array.from({ length: 6 }, (e, t) => /* @__PURE__ */ y("tr", { children: Array.from({ length: 7 }, (e, s) => {
|
|
135
|
+
let c = p(o, t * 7 + s), l = c.slice(0, 7) === r;
|
|
136
136
|
if (!l && C > 1) return /* @__PURE__ */ y("td", { role: "gridcell" }, c);
|
|
137
137
|
let u = c === Z, d = c === Q, f = !!Z && !!Q && c > Z && c < Q, m = c === N || c === M?.start || c === M?.end, h = xe(c);
|
|
138
138
|
return /* @__PURE__ */ y("td", {
|
|
139
139
|
role: "gridcell",
|
|
140
140
|
"aria-selected": m || f || void 0,
|
|
141
|
-
className:
|
|
141
|
+
className: n("p-0", (f || (u || d) && Z !== Q) && "bg-primary/15", u && "rounded-s-lg", d && "rounded-e-lg", f && (s === 0 || C > 1 && c === i) && "rounded-s-lg", f && (s === 6 || C > 1 && c === a) && "rounded-e-lg"),
|
|
142
142
|
children: /* @__PURE__ */ y("button", {
|
|
143
143
|
type: "button",
|
|
144
144
|
"data-date": c,
|
|
@@ -152,11 +152,11 @@ function se(se) {
|
|
|
152
152
|
B(c), X && H(c);
|
|
153
153
|
},
|
|
154
154
|
onMouseEnter: () => X && H(c),
|
|
155
|
-
className:
|
|
155
|
+
className: n(ce, !l && "text-muted-foreground", h && "cursor-not-allowed opacity-35", m ? "bg-primary text-primary-foreground shadow-[0_0_20px_-4px_oklch(var(--glow)/calc(0.8*var(--glow-k)))]" : !h && "hover:bg-tint/[0.08]", c === I && "after:bg-primary after:absolute after:bottom-1 after:left-1/2 after:size-1 after:-translate-x-1/2 after:rounded-full", c === I && m && "after:bg-primary-foreground"),
|
|
156
156
|
children: _e.format(Number(c.slice(8)))
|
|
157
157
|
})
|
|
158
158
|
}, c);
|
|
159
|
-
}) },
|
|
159
|
+
}) }, t)) })
|
|
160
160
|
]
|
|
161
161
|
}, r);
|
|
162
162
|
})
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useLocale as e } from "../locale-provider/index.js";
|
|
3
|
+
import { cx as t } from "../utils/cx.js";
|
|
4
4
|
import { formatMonth as n } from "../utils/month.js";
|
|
5
5
|
import { dayOfWeek as r, daysInMonth as i, formatDate as a, weekStart as o, weekdayNames as s } from "../utils/date.js";
|
|
6
6
|
import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
7
7
|
//#region packages/calendar-heatmap/index.tsx
|
|
8
8
|
function d({ month: d, values: f, locale: p, format: m = String, weekStartsOn: h, onSelectedChange: g, selected: _, label: v, className: y, ...b }) {
|
|
9
|
-
let x =
|
|
9
|
+
let x = e(p), S = new Intl.NumberFormat(x), C = h ?? o(x), w = i(d), T = Array.from({ length: w }, (e, t) => `${d}-${String(t + 1).padStart(2, "0")}`), E = (r(T[0]) - C + 7) % 7, D = [...Array(E).fill(null), ...T];
|
|
10
10
|
for (; D.length % 7;) D.push(null);
|
|
11
11
|
let O = Array.from({ length: D.length / 7 }, (e, t) => D.slice(t * 7, t * 7 + 7)), k = s(x, "narrow"), A = s(x, "long"), j = Array.from({ length: 7 }, (e, t) => (C + t) % 7), M = Math.max(0, ...T.map((e) => f[e] ?? 0));
|
|
12
12
|
return /* @__PURE__ */ u("table", {
|
|
13
13
|
"aria-label": v ?? n(d, x, "long"),
|
|
14
14
|
...b,
|
|
15
|
-
className:
|
|
15
|
+
className: t("zen__calendar-heatmap w-full table-fixed border-separate border-spacing-1", y),
|
|
16
16
|
children: [/* @__PURE__ */ l("thead", { children: /* @__PURE__ */ l("tr", { children: j.map((e) => /* @__PURE__ */ l("th", {
|
|
17
17
|
scope: "col",
|
|
18
18
|
abbr: A[e],
|
|
19
19
|
className: "text-muted-foreground pb-1 text-xs font-normal",
|
|
20
20
|
children: k[e]
|
|
21
|
-
}, e)) }) }), /* @__PURE__ */ l("tbody", { children: O.map((
|
|
22
|
-
if (!
|
|
23
|
-
let r = f[
|
|
21
|
+
}, e)) }) }), /* @__PURE__ */ l("tbody", { children: O.map((e, n) => /* @__PURE__ */ l("tr", { children: e.map((e, n) => {
|
|
22
|
+
if (!e) return /* @__PURE__ */ l("td", {}, n);
|
|
23
|
+
let r = f[e], i = M > 0 && r ? Math.sqrt(r / M) : 0, o = `${a(e, x, "day")}: ${m(r || 0)}`, s = t("relative grid aspect-square w-full place-items-center rounded-md text-[0.65rem] tabular-nums transition-[box-shadow]", i ? i > .6 ? "text-primary-foreground" : "text-foreground/80" : "bg-tint/[0.04] text-muted-foreground", e === _ && "ring-ring ring-2"), d = i ? { background: `oklch(var(--primary) / ${+(.14 + .81 * i).toFixed(2)})` } : void 0, p = /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("span", {
|
|
24
24
|
"aria-hidden": !0,
|
|
25
|
-
children: S.format(Number(
|
|
25
|
+
children: S.format(Number(e.slice(8)))
|
|
26
26
|
}), /* @__PURE__ */ l("span", {
|
|
27
27
|
className: "sr-only",
|
|
28
28
|
children: o
|
|
@@ -32,9 +32,9 @@ function d({ month: d, values: f, locale: p, format: m = String, weekStartsOn: h
|
|
|
32
32
|
className: "p-0",
|
|
33
33
|
children: g ? /* @__PURE__ */ l("button", {
|
|
34
34
|
type: "button",
|
|
35
|
-
"aria-pressed":
|
|
36
|
-
onClick: () => g(
|
|
37
|
-
className:
|
|
35
|
+
"aria-pressed": e === _,
|
|
36
|
+
onClick: () => g(e),
|
|
37
|
+
className: t(s, " cursor-pointer outline-hidden hover:shadow-[0_0_0_1px_oklch(var(--tint)/0.3)] focus-ring"),
|
|
38
38
|
style: d,
|
|
39
39
|
children: p
|
|
40
40
|
}) : /* @__PURE__ */ l("span", {
|
|
@@ -42,7 +42,7 @@ function d({ month: d, values: f, locale: p, format: m = String, weekStartsOn: h
|
|
|
42
42
|
style: d,
|
|
43
43
|
children: p
|
|
44
44
|
})
|
|
45
|
-
},
|
|
45
|
+
}, e);
|
|
46
46
|
}) }, n)) })]
|
|
47
47
|
});
|
|
48
48
|
}
|
package/dist/canvas/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { useMessages as e } from "../locale-provider/index.js";
|
|
3
|
+
import { cx as t } from "../utils/cx.js";
|
|
4
|
+
import { useMergedRefs as n } from "../utils/refs.js";
|
|
5
5
|
import { boundsOf as r, intersects as i, moveRect as a, resizeRect as o } from "./geometry.js";
|
|
6
6
|
import { createContext as s, useContext as c, useEffect as l, useId as u, useLayoutEffect as d, useRef as f, useState as p } from "react";
|
|
7
7
|
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
@@ -31,7 +31,7 @@ var g = typeof window > "u" ? l : d, _ = 3, ee = "input, textarea, select, butto
|
|
|
31
31
|
ArrowDown: [0, 1]
|
|
32
32
|
}, x = (e, t) => e.x === t.x && e.y === t.y && e.w === t.w && e.h === t.h, S = (e, t) => e.length === t.length && e.every((e, n) => e === t[n]), C = s(null);
|
|
33
33
|
function w({ width: s, height: c, scale: l = 1, items: d, onItemsChange: v, onItemsChangeEnd: y, selected: w = [], onSelectedChange: T, minSize: E = 8, snap: D = !1, grid: O, className: te, style: ne, children: re, onPointerDown: ie, ref: ae, ...k }) {
|
|
34
|
-
let A =
|
|
34
|
+
let A = e(), j = f(null), oe = n(j, ae), M = f(!1), [N, se] = p(null), [ce, P] = p([]), [F, I] = p(null), [L, R] = p(null), [le, z] = p(!1), [B, V] = p(""), H = u();
|
|
35
35
|
g(() => {
|
|
36
36
|
let e = j.current;
|
|
37
37
|
if (l !== "fit" || !e) return;
|
|
@@ -190,7 +190,7 @@ function w({ width: s, height: c, scale: l = 1, items: d, onItemsChange: v, onIt
|
|
|
190
190
|
height: c * U
|
|
191
191
|
}
|
|
192
192
|
},
|
|
193
|
-
className:
|
|
193
|
+
className: t("zen__canvas bg-tint/[0.03] relative shrink-0 overflow-hidden rounded-lg shadow-[inset_0_0_0_1px_oklch(var(--tint)/0.08)] select-none", te),
|
|
194
194
|
children: [/* @__PURE__ */ m("div", {
|
|
195
195
|
style: {
|
|
196
196
|
width: s,
|
|
@@ -198,7 +198,7 @@ function w({ width: s, height: c, scale: l = 1, items: d, onItemsChange: v, onIt
|
|
|
198
198
|
scale: String(U),
|
|
199
199
|
"--canvas-scale": U
|
|
200
200
|
},
|
|
201
|
-
className:
|
|
201
|
+
className: t("absolute top-0 left-0 origin-top-left", l === "fit" && N === null && "invisible"),
|
|
202
202
|
children: re
|
|
203
203
|
}), /* @__PURE__ */ h("div", {
|
|
204
204
|
"aria-hidden": !0,
|
|
@@ -260,30 +260,30 @@ function w({ width: s, height: c, scale: l = 1, items: d, onItemsChange: v, onIt
|
|
|
260
260
|
]
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
|
-
function T({ id:
|
|
263
|
+
function T({ id: e, label: n, className: r, style: i, children: a, ...o }) {
|
|
264
264
|
let s = c(C);
|
|
265
265
|
if (!s) throw Error("<CanvasItem> must be inside <Canvas>");
|
|
266
|
-
let l = s.item(
|
|
266
|
+
let l = s.item(e);
|
|
267
267
|
if (!l) return null;
|
|
268
|
-
let u = s.selected.includes(
|
|
268
|
+
let u = s.selected.includes(e), d = u && s.selected.length === 1;
|
|
269
269
|
return /* @__PURE__ */ h("div", {
|
|
270
270
|
role: "group",
|
|
271
271
|
"aria-roledescription": l.locked ? "locked item" : "movable item",
|
|
272
272
|
"aria-label": n,
|
|
273
273
|
"aria-describedby": l.locked ? void 0 : s.hintId,
|
|
274
274
|
tabIndex: 0,
|
|
275
|
-
"data-canvas-id":
|
|
275
|
+
"data-canvas-id": e,
|
|
276
276
|
"data-selected": u || void 0,
|
|
277
277
|
"data-locked": l.locked || void 0,
|
|
278
278
|
...o,
|
|
279
|
-
onFocus: (
|
|
280
|
-
o.onFocus?.(
|
|
279
|
+
onFocus: (t) => {
|
|
280
|
+
o.onFocus?.(t), t.target === t.currentTarget && s.focus(e);
|
|
281
281
|
},
|
|
282
|
-
onPointerDown: (
|
|
283
|
-
o.onPointerDown?.(
|
|
282
|
+
onPointerDown: (t) => {
|
|
283
|
+
o.onPointerDown?.(t), s.grab(t, e, n);
|
|
284
284
|
},
|
|
285
|
-
onKeyDown: (
|
|
286
|
-
o.onKeyDown?.(
|
|
285
|
+
onKeyDown: (t) => {
|
|
286
|
+
o.onKeyDown?.(t), s.key(t, e, n);
|
|
287
287
|
},
|
|
288
288
|
style: {
|
|
289
289
|
...i,
|
|
@@ -292,12 +292,12 @@ function T({ id: t, label: n, className: r, style: i, children: a, ...o }) {
|
|
|
292
292
|
width: l.w,
|
|
293
293
|
height: l.h
|
|
294
294
|
},
|
|
295
|
-
className:
|
|
295
|
+
className: t("zen__canvas-item absolute cursor-move touch-none outline-hidden data-locked:cursor-default data-locked:touch-auto", "[outline-offset:calc(1px/var(--canvas-scale))]", "not-data-selected:hover:outline-solid not-data-selected:hover:outline-[length:calc(1px/var(--canvas-scale))] not-data-selected:hover:outline-[color:oklch(var(--tint)/0.35)]", "data-selected:outline-solid data-selected:outline-[length:calc(2px/var(--canvas-scale))] data-selected:outline-[color:oklch(var(--primary)/0.8)]", "focus-visible:outline-solid focus-visible:outline-[length:calc(2px/var(--canvas-scale))] focus-visible:outline-[color:oklch(var(--ring)/0.7)]", r),
|
|
296
296
|
children: [a, d && !l.locked && v.map((r) => /* @__PURE__ */ m("span", {
|
|
297
297
|
"aria-hidden": !0,
|
|
298
298
|
"data-handle": r,
|
|
299
|
-
onPointerDown: (
|
|
300
|
-
className:
|
|
299
|
+
onPointerDown: (t) => s.grab(t, e, n, r),
|
|
300
|
+
className: t("bg-foreground absolute z-10 size-[calc(10px/var(--canvas-scale))] -translate-1/2 rounded-full border-[length:calc(2px/var(--canvas-scale))] border-[color:oklch(var(--primary))] shadow-[0_0_8px_oklch(var(--glow)/0.6)]", "after:absolute after:-inset-[calc(6px/var(--canvas-scale))] pointer-coarse:after:-inset-[calc(14px/var(--canvas-scale))]", y[r])
|
|
301
301
|
}, r))]
|
|
302
302
|
});
|
|
303
303
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/carousel/index.tsx"],"names":[],"mappings":"AAMA,OAAO,EACH,cAAc,EASjB,MAAM,OAAO,CAAC;AA8Bf;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/carousel/index.tsx"],"names":[],"mappings":"AAMA,OAAO,EACH,cAAc,EASjB,MAAM,OAAO,CAAC;AA8Bf;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+BA0E/E;AAED,mCAAmC;AACnC,wBAAgB,eAAe,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,+BAiBjF;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,+BAoB9E;AAKD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,+BAoBzF;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,+BAmBrF;AAED,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,sCA6BzE;AAED,8GAA8G;AAC9G,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,+BAE7E;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC"}
|