plass-ui 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/CHANGELOG.md +432 -0
  2. package/README.md +45 -23
  3. package/dist/components/accordion/PlAccordion.d.ts +1 -1
  4. package/dist/components/alert/PlAlert.js +1 -1
  5. package/dist/components/anchor/PlAnchor.d.ts +14 -1
  6. package/dist/components/anchor/PlAnchor.js +1 -1
  7. package/dist/components/animate-appear/PlAnimateAppear.js +1 -1
  8. package/dist/components/animate-blink/PlAnimateBlink.js +1 -1
  9. package/dist/components/animate-counter/PlAnimateCounter.js +1 -1
  10. package/dist/components/animate-fade/PlAnimateFade.js +1 -1
  11. package/dist/components/animate-float/PlAnimateFloat.js +1 -1
  12. package/dist/components/animate-grow/PlAnimateGrow.js +1 -1
  13. package/dist/components/animate-headline/PlAnimateHeadline.js +1 -1
  14. package/dist/components/animate-lighting/PlAnimateLighting.js +1 -1
  15. package/dist/components/animate-marquee/PlAnimateMarquee.d.ts +16 -4
  16. package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -1
  17. package/dist/components/animate-reveal/PlAnimateReveal.js +1 -1
  18. package/dist/components/animate-rotate/PlAnimateRotate.js +1 -1
  19. package/dist/components/animate-scramble/PlAnimateScramble.js +1 -1
  20. package/dist/components/animate-shake/PlAnimateShake.js +1 -1
  21. package/dist/components/animate-slide/PlAnimateSlide.js +1 -1
  22. package/dist/components/animate-split/PlAnimateSplit.d.ts +7 -4
  23. package/dist/components/animate-split/PlAnimateSplit.js +1 -1
  24. package/dist/components/animate-typing/PlAnimateTyping.d.ts +3 -2
  25. package/dist/components/animate-typing/PlAnimateTyping.js +1 -1
  26. package/dist/components/animate-zoom/PlAnimateZoom.js +1 -1
  27. package/dist/components/app-logo/PlAppLogo.js +1 -1
  28. package/dist/components/area-chart/PlAreaChart.d.ts +1 -1
  29. package/dist/components/area-chart/PlAreaChart.js +1 -1
  30. package/dist/components/aspect-ratio/PlAspectRatio.d.ts +2 -1
  31. package/dist/components/aspect-ratio/PlAspectRatio.js +1 -1
  32. package/dist/components/avatar/PlAvatar.js +1 -1
  33. package/dist/components/back-top/PlBackTop.d.ts +8 -1
  34. package/dist/components/back-top/PlBackTop.js +1 -1
  35. package/dist/components/badge/PlBadge.js +1 -1
  36. package/dist/components/bar-chart/PlBarChart.d.ts +1 -1
  37. package/dist/components/bar-chart/PlBarChart.js +1 -1
  38. package/dist/components/blockquote/PlBlockquote.js +1 -1
  39. package/dist/components/bottom-navigation/PlBottomNavigation.d.ts +3 -0
  40. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
  41. package/dist/components/button/PlButton.d.ts +8 -0
  42. package/dist/components/button/PlButton.js +1 -1
  43. package/dist/components/calendar/PlCalendar.js +1 -1
  44. package/dist/components/card/PlCard.js +1 -1
  45. package/dist/components/carousel/PlCarousel.d.ts +1 -1
  46. package/dist/components/carousel/PlCarousel.js +1 -1
  47. package/dist/components/chat-bubble/PlChatBubble.d.ts +4 -1
  48. package/dist/components/chat-bubble/PlChatBubble.js +1 -1
  49. package/dist/components/checkbox/PlCheckbox.js +1 -1
  50. package/dist/components/chip/PlChip.d.ts +6 -2
  51. package/dist/components/chip/PlChip.js +1 -1
  52. package/dist/components/code-block/PlCodeBlock.d.ts +19 -2
  53. package/dist/components/code-block/PlCodeBlock.js +1 -1
  54. package/dist/components/color-picker/PlColorPicker.d.ts +19 -2
  55. package/dist/components/color-picker/PlColorPicker.js +1 -1
  56. package/dist/components/combobox/PlCombobox.d.ts +14 -7
  57. package/dist/components/combobox/PlCombobox.js +1 -1
  58. package/dist/components/command-palette/PlCommandPalette.d.ts +6 -2
  59. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  60. package/dist/components/confirm/PlConfirmProvider.js +1 -1
  61. package/dist/components/container/PlContainer.js +1 -1
  62. package/dist/components/data-table/PlDataTable.d.ts +20 -6
  63. package/dist/components/data-table/PlDataTable.js +1 -1
  64. package/dist/components/date-picker/PlDatePicker.js +1 -1
  65. package/dist/components/date-range-picker/PlDateRangePicker.js +1 -1
  66. package/dist/components/date-time-picker/PlDateTimePicker.js +1 -1
  67. package/dist/components/drawer/PlDrawer.js +1 -1
  68. package/dist/components/empty/PlEmpty.js +1 -1
  69. package/dist/components/file-picker/PlFilePicker.d.ts +22 -3
  70. package/dist/components/file-picker/PlFilePicker.js +1 -1
  71. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.d.ts +3 -0
  72. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
  73. package/dist/components/form/PlForm.js +1 -1
  74. package/dist/components/gallery/PlGallery.d.ts +40 -2
  75. package/dist/components/gallery/PlGallery.js +1 -1
  76. package/dist/components/gallery/PlGalleryViewer.js +1 -1
  77. package/dist/components/gauge-chart/PlGaugeChart.js +1 -1
  78. package/dist/components/heatmap-chart/PlHeatmapChart.js +1 -1
  79. package/dist/components/highlight/PlHighlight.d.ts +10 -3
  80. package/dist/components/highlight/PlHighlight.js +1 -1
  81. package/dist/components/hot-keys/PlHotKeys.js +1 -1
  82. package/dist/components/hover-card/PlHoverCard.d.ts +5 -3
  83. package/dist/components/hover-card/PlHoverCard.js +1 -1
  84. package/dist/components/how-to-steps/PlHowToSteps.js +1 -1
  85. package/dist/components/image/PlImage.d.ts +195 -8
  86. package/dist/components/image/PlImage.js +1 -1
  87. package/dist/components/image/PlImagePreview.d.ts +58 -0
  88. package/dist/components/image/PlImagePreview.js +1 -0
  89. package/dist/components/image/index.d.ts +1 -1
  90. package/dist/components/list/PlList.js +1 -1
  91. package/dist/components/menu/PlMenu.d.ts +14 -5
  92. package/dist/components/menu/PlMenu.js +1 -1
  93. package/dist/components/meter/PlMeter.js +1 -1
  94. package/dist/components/navigation-menu/PlNavigationMenu.d.ts +7 -1
  95. package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
  96. package/dist/components/number-field/PlNumberField.d.ts +12 -4
  97. package/dist/components/number-field/PlNumberField.js +1 -1
  98. package/dist/components/otp-field/PlOtpField.d.ts +15 -1
  99. package/dist/components/otp-field/PlOtpField.js +1 -1
  100. package/dist/components/page-layout/PlPageLayout.js +1 -1
  101. package/dist/components/pagination/PlPagination.d.ts +12 -9
  102. package/dist/components/pagination/PlPagination.js +1 -1
  103. package/dist/components/panes/PlPanes.d.ts +5 -0
  104. package/dist/components/panes/PlPanes.js +1 -1
  105. package/dist/components/pie-chart/PlPieChart.js +1 -1
  106. package/dist/components/pill/PlPill.js +1 -1
  107. package/dist/components/popover/PlPopover.d.ts +5 -5
  108. package/dist/components/popover/PlPopover.js +1 -1
  109. package/dist/components/progress-box/PlProgressBox.js +1 -1
  110. package/dist/components/progress-circular/PlProgressCircular.js +1 -1
  111. package/dist/components/progress-linear/PlProgressLinear.js +1 -1
  112. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  113. package/dist/components/rating/PlRating.d.ts +1 -1
  114. package/dist/components/rating/PlRating.js +1 -1
  115. package/dist/components/scatter-chart/PlScatterChart.js +1 -1
  116. package/dist/components/scroll-area/PlScrollArea.js +1 -1
  117. package/dist/components/scroll-zone/PlScrollZone.d.ts +19 -6
  118. package/dist/components/scroll-zone/PlScrollZone.js +1 -1
  119. package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
  120. package/dist/components/select/PlSelect.d.ts +8 -2
  121. package/dist/components/select/PlSelect.js +1 -1
  122. package/dist/components/show/PlShow.d.ts +16 -0
  123. package/dist/components/show/PlShow.js +1 -1
  124. package/dist/components/sidebar/PlSidebar.js +1 -1
  125. package/dist/components/sidebar/PlSidebarTrigger.js +1 -1
  126. package/dist/components/skeleton/PlSkeleton.js +1 -1
  127. package/dist/components/slider/PlSlider.d.ts +13 -1
  128. package/dist/components/slider/PlSlider.js +1 -1
  129. package/dist/components/sparkline/PlSparkline.js +1 -1
  130. package/dist/components/spoiler/PlSpoiler.d.ts +15 -8
  131. package/dist/components/spoiler/PlSpoiler.js +1 -1
  132. package/dist/components/stat/PlStat.d.ts +4 -0
  133. package/dist/components/stat/PlStat.js +1 -1
  134. package/dist/components/stepper/PlStepper.d.ts +1 -1
  135. package/dist/components/stepper/PlStepper.js +1 -1
  136. package/dist/components/switch/PlSwitch.js +1 -1
  137. package/dist/components/table/PlTable.d.ts +5 -5
  138. package/dist/components/tabs/PlTabs.d.ts +26 -1
  139. package/dist/components/tabs/PlTabs.js +1 -1
  140. package/dist/components/text-field/PlTextField.d.ts +15 -5
  141. package/dist/components/text-field/PlTextField.js +1 -1
  142. package/dist/components/text-link/PlTextLink.js +1 -1
  143. package/dist/components/time-picker/PlTimePicker.js +1 -1
  144. package/dist/components/timeline/PlTimeline.js +1 -1
  145. package/dist/components/timeline-chart/PlTimelineChart.js +1 -1
  146. package/dist/components/toast/PlToast.js +1 -1
  147. package/dist/components/toggle/PlToggle.js +1 -1
  148. package/dist/components/tooltip/PlTooltip.js +1 -1
  149. package/dist/components/tour/PlTour.js +1 -1
  150. package/dist/components/transfer/PlTransfer.d.ts +10 -1
  151. package/dist/components/transfer/PlTransfer.js +1 -1
  152. package/dist/components/tree/PlTree.js +1 -1
  153. package/dist/components/tree-select/PlTreeSelect.js +1 -1
  154. package/dist/components/typography/PlTypography.js +1 -1
  155. package/dist/components/window-pane/PlWindowPane.d.ts +3 -3
  156. package/dist/components/window-pane/PlWindowPane.js +1 -1
  157. package/dist/css/area-chart.css +1 -0
  158. package/dist/css/back-top.css +2 -0
  159. package/dist/css/bar-chart.css +1 -0
  160. package/dist/css/calendar.css +1 -0
  161. package/dist/css/carousel.css +2 -0
  162. package/dist/css/color-picker.css +1 -0
  163. package/dist/css/combobox.css +1 -0
  164. package/dist/css/command-palette.css +1 -0
  165. package/dist/css/confirm.css +2 -0
  166. package/dist/css/data-table.css +5 -0
  167. package/dist/css/date-picker.css +1 -0
  168. package/dist/css/date-range-picker.css +1 -0
  169. package/dist/css/date-time-picker.css +1 -0
  170. package/dist/css/floating-action-button.css +2 -0
  171. package/dist/css/gallery.css +5 -0
  172. package/dist/css/gauge-chart.css +1 -0
  173. package/dist/css/heatmap-chart.css +1 -0
  174. package/dist/css/icon-button.css +1 -0
  175. package/dist/css/image.css +2 -0
  176. package/dist/css/line-chart.css +1 -0
  177. package/dist/css/menubar.css +1 -0
  178. package/dist/css/pagination.css +1 -0
  179. package/dist/css/pie-chart.css +1 -0
  180. package/dist/css/popconfirm.css +2 -0
  181. package/dist/css/scatter-chart.css +1 -0
  182. package/dist/css/scroll-zone.css +2 -0
  183. package/dist/css/sidebar.css +3 -0
  184. package/dist/css/sparkline.css +1 -0
  185. package/dist/css/spoiler.css +1 -0
  186. package/dist/css/stat.css +1 -0
  187. package/dist/css/time-picker.css +1 -0
  188. package/dist/css/timeline-chart.css +1 -0
  189. package/dist/css/tour.css +1 -0
  190. package/dist/css/transfer.css +4 -0
  191. package/dist/css/tree-select.css +2 -0
  192. package/dist/hooks/usePlElementSize.d.ts +4 -1
  193. package/dist/hooks/usePlElementSize.js +1 -1
  194. package/dist/hooks/usePlHotKeys.d.ts +5 -1
  195. package/dist/hooks/usePlHotKeys.js +1 -1
  196. package/dist/hooks/usePlOnScreen.d.ts +4 -0
  197. package/dist/hooks/usePlOnScreen.js +1 -1
  198. package/dist/internal/animate.d.ts +24 -21
  199. package/dist/internal/animate.js +1 -1
  200. package/dist/internal/calendar.js +1 -1
  201. package/dist/internal/chart-frame.d.ts +3 -14
  202. package/dist/internal/chart-frame.js +1 -1
  203. package/dist/internal/chart-line.js +1 -1
  204. package/dist/internal/chart.d.ts +90 -3
  205. package/dist/internal/chart.js +1 -1
  206. package/dist/internal/color-scheme.js +1 -1
  207. package/dist/internal/data-table.d.ts +5 -4
  208. package/dist/internal/data-table.js +1 -1
  209. package/dist/internal/date.d.ts +10 -0
  210. package/dist/internal/date.js +1 -1
  211. package/dist/internal/defaults.d.ts +14 -1
  212. package/dist/internal/drag.d.ts +16 -0
  213. package/dist/internal/drag.js +1 -1
  214. package/dist/internal/focusable.d.ts +8 -0
  215. package/dist/internal/focusable.js +1 -0
  216. package/dist/internal/form.d.ts +61 -0
  217. package/dist/internal/form.js +1 -0
  218. package/dist/internal/gallery.d.ts +60 -14
  219. package/dist/internal/gallery.js +1 -1
  220. package/dist/internal/glow.d.ts +32 -0
  221. package/dist/internal/glow.js +1 -0
  222. package/dist/internal/highlight.js +1 -1
  223. package/dist/internal/image.d.ts +94 -0
  224. package/dist/internal/image.js +1 -0
  225. package/dist/internal/inert.d.ts +19 -0
  226. package/dist/internal/inert.js +1 -0
  227. package/dist/internal/keys.d.ts +19 -0
  228. package/dist/internal/keys.js +1 -1
  229. package/dist/internal/labels.d.ts +58 -1
  230. package/dist/internal/labels.js +1 -1
  231. package/dist/internal/link.d.ts +17 -0
  232. package/dist/internal/link.js +1 -1
  233. package/dist/internal/notch.d.ts +83 -0
  234. package/dist/internal/notch.js +1 -0
  235. package/dist/internal/page-layout.d.ts +14 -7
  236. package/dist/internal/page-layout.js +1 -1
  237. package/dist/internal/picker.d.ts +51 -8
  238. package/dist/internal/picker.js +1 -1
  239. package/dist/internal/progress.d.ts +16 -8
  240. package/dist/internal/progress.js +1 -1
  241. package/dist/internal/scramble.d.ts +4 -0
  242. package/dist/internal/scramble.js +1 -1
  243. package/dist/internal/scroll-target.d.ts +5 -0
  244. package/dist/internal/scroll-target.js +1 -0
  245. package/dist/internal/steps.js +1 -1
  246. package/dist/internal/styles.d.ts +87 -0
  247. package/dist/internal/styles.js +1 -1
  248. package/dist/internal/text.d.ts +39 -0
  249. package/dist/internal/text.js +1 -0
  250. package/dist/internal/watermark.d.ts +44 -0
  251. package/dist/internal/watermark.js +1 -0
  252. package/dist/internal/wheel.d.ts +52 -0
  253. package/dist/internal/wheel.js +1 -0
  254. package/dist/internal/window.js +1 -1
  255. package/dist/locales/de.js +1 -1
  256. package/dist/locales/es.js +1 -1
  257. package/dist/locales/fr.js +1 -1
  258. package/dist/locales/ja.js +1 -1
  259. package/dist/locales/ko.js +1 -1
  260. package/dist/locales/zh-Hans.js +1 -1
  261. package/dist/provider/PlColorSchemeScript.js +1 -1
  262. package/dist/provider/PlassProvider.d.ts +4 -3
  263. package/dist/provider/PlassProvider.js +1 -1
  264. package/dist/styles.css +1 -1
  265. package/dist/tailwind.css +313 -15
  266. package/dist/tokens.css +313 -15
  267. package/dist/types.d.ts +71 -29
  268. package/package.json +15 -15
@@ -1,2 +1,3 @@
1
1
  /* Scan manifest for <scatter-chart>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/scatter-chart';
3
+ @source '../components/box';
@@ -1,2 +1,4 @@
1
1
  /* Scan manifest for <scroll-zone>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/scroll-zone';
3
+ @source '../components/button';
4
+ @source '../components/icon-button';
@@ -1,2 +1,5 @@
1
1
  /* Scan manifest for <sidebar>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/sidebar';
3
+ @source '../components/button';
4
+ @source '../components/drawer';
5
+ @source '../components/icon-button';
@@ -1,2 +1,3 @@
1
1
  /* Scan manifest for <sparkline>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/sparkline';
3
+ @source '../components/box';
@@ -1,2 +1,3 @@
1
1
  /* Scan manifest for <spoiler>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/spoiler';
3
+ @source '../components/button';
package/dist/css/stat.css CHANGED
@@ -1,2 +1,3 @@
1
1
  /* Scan manifest for <stat>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/stat';
3
+ @source '../components/skeleton';
@@ -1,2 +1,3 @@
1
1
  /* Scan manifest for <time-picker>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/time-picker';
3
+ @source '../components/button';
@@ -1,2 +1,3 @@
1
1
  /* Scan manifest for <timeline-chart>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/timeline-chart';
3
+ @source '../components/box';
package/dist/css/tour.css CHANGED
@@ -1,2 +1,3 @@
1
1
  /* Scan manifest for <tour>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/tour';
3
+ @source '../components/button';
@@ -1,2 +1,6 @@
1
1
  /* Scan manifest for <transfer>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/transfer';
3
+ @source '../components/button';
4
+ @source '../components/checkbox';
5
+ @source '../components/icon-button';
6
+ @source '../components/text-field';
@@ -1,2 +1,4 @@
1
1
  /* Scan manifest for <tree-select>. Needs `plass-ui/css/base.css` first. */
2
2
  @source '../components/tree-select';
3
+ @source '../components/text-field';
4
+ @source '../components/tree';
@@ -20,7 +20,10 @@ export interface PlElementSize {
20
20
  *
21
21
  * `null` until there is an element to measure, which is the honest answer on a
22
22
  * server and on the first render: guessing `0` there would let a caller divide
23
- * by it.
23
+ * by it. The ref is read again after every render, so an element that is
24
+ * attached later — `loading ? <Spinner /> : <div ref={box}>` — or swapped for
25
+ * another is measured from the moment it is there, and the answer goes back to
26
+ * `null` while there is none.
24
27
  *
25
28
  * @example
26
29
  * const box = React.useRef<HTMLDivElement>(null);
@@ -1 +1 @@
1
- "use client";import*as t from"react";export function usePlElementSize(e){const[n,i]=t.useState(null);return t.useLayoutEffect(()=>{const t=e.current;if(!t)return;const read=()=>{const e=function contentBoxOf(t){const e=getComputedStyle(t),n=parseFloat(e.paddingInlineStart)+parseFloat(e.paddingInlineEnd),i=parseFloat(e.paddingBlockStart)+parseFloat(e.paddingBlockEnd);return{width:Math.max(0,t.clientWidth-n),height:Math.max(0,t.clientHeight-i)}}(t);i(t=>t?.width===e.width&&t.height===e.height?t:e)};if(read(),"undefined"==typeof ResizeObserver)return;const n=new ResizeObserver(read);return n.observe(t),()=>n.disconnect()},[e]),n}
1
+ "use client";import*as e from"react";export function usePlElementSize(t){const[n,r]=e.useState(null),[i,o]=e.useState(null);return e.useLayoutEffect(()=>{t.current!==i&&o(t.current)}),e.useLayoutEffect(()=>{if(!i)return void r(null);const read=()=>{const e=function contentBoxOf(e){const t=getComputedStyle(e),n=parseFloat(t.paddingInlineStart)+parseFloat(t.paddingInlineEnd),r=parseFloat(t.paddingBlockStart)+parseFloat(t.paddingBlockEnd);return{width:Math.max(0,e.clientWidth-n),height:Math.max(0,e.clientHeight-r)}}(i);r(t=>t?.width===e.width&&t.height===e.height?t:e)};if(read(),"undefined"==typeof ResizeObserver)return;const e=new ResizeObserver(read);return e.observe(i),()=>e.disconnect()},[i]),n}
@@ -55,7 +55,7 @@ export interface PlHotKeysOptions {
55
55
  * this way since it existed, with a private copy of the matcher — and an
56
56
  * application's own shortcuts are the reason it is public.
57
57
  *
58
- * Three rules it shares with the `hotKeys` prop:
58
+ * Five rules it shares with the `hotKeys` prop:
59
59
  *
60
60
  * - **A modifier is checked in both directions.** `Enter` does not fire on
61
61
  * `Shift+Enter`, and `Mod+K` does not fire on `Mod+Shift+K`.
@@ -66,6 +66,10 @@ export interface PlHotKeysOptions {
66
66
  * - **These are chords rather than letters.** A single unmodified key is
67
67
  * allowed and is sometimes right (`?` for help), but it is the case
68
68
  * `whileTyping` is about.
69
+ * - **A chord names the key, not the character it types.** `Alt+K` answers
70
+ * the `˚` Option+K types on a Mac, and `?` needs no `Shift+`.
71
+ * - **A key an input method is composing is left alone**, so the Enter that
72
+ * commits a syllable fires nothing.
69
73
  *
70
74
  * The handlers are read fresh on every keystroke, so an inline object literal
71
75
  * costs nothing and a handler closing over current state is never stale. What
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{editsText as n,hasHardModifier as t,isTypingTarget as r,matchesHotKey as o}from"../internal/keys.js";export function usePlHotKeys(i,u={}){const{enabled:s=!0,target:f,whileTyping:c=!1}=u,l=e.useRef(i);e.useEffect(()=>{l.current=i});const d=Object.keys(i??{}).join("\n");e.useEffect(()=>{const e=function resolve(e){return void 0===e?"undefined"==typeof window?null:window:null===e?null:"current"in e?e.current:e}(f);if(!s||!e||""===d)return;const i=d.split("\n"),onKeyDown=e=>{const u=e;if(!u.defaultPrevented)for(const e of i)if(o(u,e)){if(!c&&!t(e)&&n(u.key)&&r(u.target))return;return u.preventDefault(),void l.current?.[e]?.()}};return e.addEventListener("keydown",onKeyDown),()=>e.removeEventListener("keydown",onKeyDown)},[d,f,s,c])}
1
+ "use client";import*as e from"react";import{editsText as n,hasHardModifier as t,isComposingKey as r,isTypingTarget as o,matchesHotKey as i}from"../internal/keys.js";export function usePlHotKeys(u,s={}){const{enabled:f=!0,target:c,whileTyping:l=!1}=s,d=e.useRef(u);e.useEffect(()=>{d.current=u});const a=Object.keys(u??{}).join("\n");e.useEffect(()=>{const e=function resolve(e){return void 0===e?"undefined"==typeof window?null:window:null===e?null:"current"in e?e.current:e}(c);if(!f||!e||""===a)return;const u=a.split("\n"),onKeyDown=e=>{const s=e;if(!s.defaultPrevented&&!r(s))for(const e of u)if(i(s,e)){if(!l&&!t(e)&&n(s.key)&&o(s.target))return;return s.preventDefault(),void d.current?.[e]?.()}};return e.addEventListener("keydown",onKeyDown),()=>e.removeEventListener("keydown",onKeyDown)},[a,c,f,l])}
@@ -43,6 +43,10 @@ export interface PlOnScreenOptions {
43
43
  * A browser with no observer is told **yes** rather than no. There is no way to
44
44
  * find out, and a picture that never loads is worse than one that loads early.
45
45
  *
46
+ * The refs are read again after every render, so an element or a `root` that is
47
+ * attached after the first one, or swapped for another, is watched from the
48
+ * moment it is there.
49
+ *
46
50
  * @example
47
51
  * const section = React.useRef<HTMLDivElement>(null);
48
52
  * const seen = usePlOnScreen(section, { rootMargin: '200px' });
@@ -1 +1 @@
1
- "use client";import*as e from"react";export function usePlOnScreen(r,{threshold:t=0,rootMargin:n,root:o,once:s=!0}={}){const[c,i]=e.useState(!1);return e.useEffect(()=>{const e=r.current;if(!e)return;if("undefined"==typeof IntersectionObserver)return void i(!0);const c=new IntersectionObserver(([e])=>{e.isIntersecting?(i(!0),s&&c.disconnect()):s||i(!1)},{threshold:t,rootMargin:n,root:o?.current??null});return c.observe(e),()=>c.disconnect()},[r,t,n,o,s]),c}
1
+ "use client";import*as e from"react";export function usePlOnScreen(t,{threshold:r=0,rootMargin:n,root:o,once:s=!0}={}){const[u,c]=e.useState(!1),[i,l]=e.useState(null),[f,a]=e.useState(null);return e.useEffect(()=>{t.current!==i&&l(t.current),(o?.current??null)!==f&&a(o?.current??null)}),e.useEffect(()=>{if(!i)return;if("undefined"==typeof IntersectionObserver)return void c(!0);const e=new IntersectionObserver(([t])=>{t.isIntersecting?(c(!0),s&&e.disconnect()):s||c(!1)},{threshold:r,rootMargin:n,root:f});return e.observe(i),()=>e.disconnect()},[i,f,r,n,s]),u}
@@ -150,28 +150,27 @@ export interface AnimationRun {
150
150
  state: 'running' | 'paused';
151
151
  /** Whether the animation has been let go at all. */
152
152
  started: boolean;
153
- /** Spread onto the element when `trigger` is `hover`; empty otherwise. */
153
+ /**
154
+ * How many times it has been started, counting every hover, every `play` and
155
+ * every change of `nonce`.
156
+ *
157
+ * `started` stays `true` from the first start on, so a second hover changes
158
+ * nothing an effect could depend on. A keyframe does not need to know, because
159
+ * it is rewound in the DOM whenever this changes. Counter, Scramble and Typing
160
+ * run their own loops in JavaScript, and they replay by listing this among
161
+ * their effects' dependencies.
162
+ */
163
+ runs: number;
164
+ /**
165
+ * The hover trigger's handlers when `trigger` is `hover`; empty otherwise.
166
+ *
167
+ * Merged with the caller's props through `mergeProps` rather than spread
168
+ * beside them. Both sides want `onPointerEnter` and `onFocus`, and a spread
169
+ * keeps only one: either a caller's prefetch never runs, or a caller's
170
+ * `onFocus` quietly takes the keyboard's way in away from the effect.
171
+ */
154
172
  handlers: React.HTMLAttributes<HTMLElement>;
155
173
  }
156
- /**
157
- * Starts, restarts and holds an animation.
158
- *
159
- * Two things here are less obvious than they look.
160
- *
161
- * **Waiting is `animation-play-state: paused`, not a second class.** An element
162
- * that has not been triggered yet has to already look like its own first frame,
163
- * or a `visible` fade would be fully drawn until it scrolled into view and then
164
- * blink out to start. With `fill-mode: both` a paused animation shows exactly
165
- * that frame, so waiting and running are one animation in two states rather
166
- * than two states to keep in step.
167
- *
168
- * **Restarting reaches for the DOM.** There is no way to rewind a CSS animation
169
- * from React: re-rendering with the same class changes nothing, and a `key`
170
- * would restart the animation by unmounting the children, taking their state
171
- * with it. Clearing `animation-name`, reading a layout property to force the
172
- * style to settle, and putting it back is the one move that rewinds the element
173
- * and leaves everything inside it alone.
174
- */
175
174
  export declare function useAnimationRun({ trigger, play, once, threshold, paused, infinite, nonce }: AnimationRunOptions): AnimationRun;
176
175
  export interface StaggerPosition extends Required<PlassAnimateStaggerProps> {
177
176
  index: number;
@@ -224,7 +223,11 @@ export interface AnimateElement {
224
223
  ref: React.RefCallback<HTMLElement>;
225
224
  className: string;
226
225
  style: React.CSSProperties;
227
- /** The hover handlers and the two data attributes, ready to be spread. */
226
+ /**
227
+ * The hover handlers and the two data attributes, to be merged with the
228
+ * caller's props through `mergeProps` for the reason `AnimationRun.handlers`
229
+ * gives.
230
+ */
228
231
  props: React.HTMLAttributes<HTMLElement> & Record<string, unknown>;
229
232
  /** The children, with the effect written onto them if it was staggered. */
230
233
  children: React.ReactNode;
@@ -1 +1 @@
1
- import*as e from"react";import{cx as n}from"./styles.js";export const animationClasses={fade:"plass-anim-fade",grow:"plass-anim-scale",slide:"plass-anim-slide",zoom:"plass-anim-scale",rotate:"plass-anim-rotate",blink:"plass-anim-blink",reveal:"plass-anim-reveal"};export const animBaseClass="plass-anim";export function lengthValue(e){return"number"==typeof e?`${e}px`:e}export function repeatValue(e){return"infinite"===e?"infinite":String(e)}export function isInfinite(e){return"infinite"===e}export function directionValue(e,n){return"out"===e?n?"alternate-reverse":"reverse":n?"alternate":"normal"}export const defaultViewRange="entry 0% cover 45%";export function animationSlots(e){const n={"--p-anim-duration":`${e.duration}ms`,"--p-anim-delay":`${e.delay}ms`,"--p-anim-repeat":repeatValue(e.repeat),"--p-anim-direction":directionValue(e.mode??"in",e.alternate)};return e.easing&&(n["--p-anim-ease"]=e.easing),"view"===e.timeline&&(n["--p-anim-timeline"]="view()",n["--p-anim-range"]=e.range??defaultViewRange),void 0!==e.opacity&&(n["--p-anim-opacity"]=String(e.opacity)),void 0!==e.scale&&(n["--p-anim-scale"]=String(e.scale)),void 0!==e.x&&(n["--p-anim-x"]=e.x),void 0!==e.y&&(n["--p-anim-y"]=e.y),void 0!==e.angle&&(n["--p-anim-angle"]=e.angle),void 0!==e.angleTo&&(n["--p-anim-angle-to"]=e.angleTo),void 0!==e.clip&&(n["--p-anim-clip"]=e.clip),n}export function revealClip(e){switch(e){case"top":return"inset(0 0 100% 0)";case"bottom":return"inset(100% 0 0 0)";case"right":return"inset(0 0 0 100%)";default:return"inset(0 100% 0 0)"}}export function slideOffsets(e,n){const t=lengthValue(n),a="number"==typeof n?-n+"px":`calc(-1 * ${t})`;switch(e){case"top":return{x:"0px",y:a};case"bottom":return{x:"0px",y:t};case"left":return{x:a,y:"0px"};default:return{x:t,y:"0px"}}}export function useAnimationRun({trigger:n,play:t,once:a,threshold:i,paused:r,infinite:s,nonce:o}){const l=e.useRef(null),[c,u]=e.useState("mount"===n),[p,m]=e.useState(0),d=e.useCallback(()=>{u(!0),m(e=>e+1)},[]);e.useLayoutEffect(()=>{const e=l.current;if(!e||0===p)return;const n=[e,...e.querySelectorAll(".plass-anim, .plass-marquee-track")];for(const e of n)e.style.animationName="none";e.offsetWidth;for(const e of n)e.style.animationName=""},[p]),e.useEffect(()=>{if("visible"!==n)return;const e=l.current;if(!e||"undefined"==typeof IntersectionObserver)return void u(!0);const t=new IntersectionObserver(([e])=>{e.isIntersecting?(d(),a&&t.disconnect()):a||u(!1)},{threshold:i});return t.observe(e),()=>t.disconnect()},[n,a,i,d]);const f=e.useRef(o);e.useEffect(()=>{Object.is(o,f.current)||(f.current=o,d())},[o,d]),e.useEffect(()=>{"manual"===n&&(t?d():u(!1))},[n,t,d]);const g="hover"===n?{onPointerEnter:d,onFocus:d,onPointerLeave:()=>{s&&u(!1)},onBlur:()=>{s&&u(!1)}}:{};return{ref:e.useCallback(e=>{l.current=e},[]),state:c&&!r?"running":"paused",started:c,handlers:g}}export function staggerSlots(e,{index:n,count:t,stagger:a,durationStep:i,reverse:r}){const s=r?t-1-n:n;return{...e,delay:e.delay+s*a,duration:Math.max(0,e.duration+s*i)}}export function animateChildren(t,a,i){const r=e.Children.toArray(t);return r.map((t,s)=>{const o=i(s,r.length);if(!e.isValidElement(t))return e.createElement("span",{key:s,className:a,style:o},t);const l=t.props;return e.cloneElement(t,{className:n(a,l.className),style:{...o,...l.style}})})}export function useAnimateElement(e){const{effect:n,trigger:t,play:a,once:i,threshold:r,paused:s,infinite:o,nonce:l,stagger:c=0,durationStep:u=0,reverse:p=!1,origin:m,children:d,...f}=e,g=useAnimationRun({trigger:"view"===f.timeline?"mount":t,play:a,once:i,threshold:r,paused:s,infinite:o,nonce:l}),y=n?`plass-anim ${animationClasses[n]}`:"",x=0!==c&&null!==n,v=void 0===m?null:{transformOrigin:m};return{ref:g.ref,className:x?"":y,style:{...v,...x?null:animationSlots(f),"--p-anim-state":g.state},props:{...g.handlers,"data-plass-animation":n??void 0,"data-state":g.state},children:x?animateChildren(d,y,(e,n)=>({...v,...animationSlots(staggerSlots(f,{index:e,count:n,stagger:c,durationStep:u,reverse:p}))})):d}}
1
+ import*as e from"react";import{cx as t}from"./styles.js";export const animationClasses={fade:"plass-anim-fade",grow:"plass-anim-scale",slide:"plass-anim-slide",zoom:"plass-anim-scale",rotate:"plass-anim-rotate",blink:"plass-anim-blink",reveal:"plass-anim-reveal"};export const animBaseClass="plass-anim";export function lengthValue(e){return"number"==typeof e?`${e}px`:e}export function repeatValue(e){return"infinite"===e?"infinite":String(e)}export function isInfinite(e){return"infinite"===e}export function directionValue(e,t){return"out"===e?t?"alternate-reverse":"reverse":t?"alternate":"normal"}export const defaultViewRange="entry 0% cover 45%";export function animationSlots(e){const t={"--p-anim-duration":`${e.duration}ms`,"--p-anim-delay":`${e.delay}ms`,"--p-anim-repeat":repeatValue(e.repeat),"--p-anim-direction":directionValue(e.mode??"in",e.alternate)};return e.easing&&(t["--p-anim-ease"]=e.easing),"view"===e.timeline&&(t["--p-anim-timeline"]="view()",t["--p-anim-range"]=e.range??defaultViewRange),void 0!==e.opacity&&(t["--p-anim-opacity"]=String(e.opacity)),void 0!==e.scale&&(t["--p-anim-scale"]=String(e.scale)),void 0!==e.x&&(t["--p-anim-x"]=e.x),void 0!==e.y&&(t["--p-anim-y"]=e.y),void 0!==e.angle&&(t["--p-anim-angle"]=e.angle),void 0!==e.angleTo&&(t["--p-anim-angle-to"]=e.angleTo),void 0!==e.clip&&(t["--p-anim-clip"]=e.clip),t}export function revealClip(e){switch(e){case"top":return"inset(0 0 100% 0)";case"bottom":return"inset(100% 0 0 0)";case"right":return"inset(0 0 0 100%)";default:return"inset(0 100% 0 0)"}}export function slideOffsets(e,t){const n=lengthValue(t),r="number"==typeof t?-t+"px":`calc(-1 * ${n})`;switch(e){case"top":return{x:"0px",y:r};case"bottom":return{x:"0px",y:n};case"left":return{x:r,y:"0px"};default:return{x:n,y:"0px"}}}function viewportRect(){const e=document.documentElement;return new DOMRect(0,0,e.clientWidth,e.clientHeight)}function holds(e,t){return null!==e&&t instanceof Node&&e.contains(t)}const n="data-plass-rewind";export function useAnimationRun({trigger:t,play:r,once:i,threshold:a,paused:o,infinite:s,nonce:l}){const c=e.useRef(null),[u,m]=e.useState("mount"===t),[p,f]=e.useState(0),d=e.useCallback(()=>{m(!0),f(e=>e+1)},[]);e.useLayoutEffect(()=>{const e=c.current;if(!e||0===p)return;const t=[e];for(const n of e.querySelectorAll(".plass-anim, .plass-marquee-track"))n.closest("[data-plass-animation]")===e&&t.push(n);e.setAttribute(n,"");for(const e of t)e.style.animationName="none";e.offsetWidth;for(const e of t)e.style.animationName="";e.removeAttribute(n)},[p]);const g=e.useRef("mount"!==t);e.useEffect(()=>{g.current=!u},[u]),e.useEffect(()=>{if("visible"!==t)return;const e=c.current;if(!e||"undefined"==typeof IntersectionObserver)return void m(!0);const n=[],r=e.parentElement;let o=r?null:viewportRect();const check=()=>{if(!o)return;const t=function visibleShare(e,t){const n=e.width*e.height;if(n<=0)return 0;const r=Math.min(e.right,t.right)-Math.max(e.left,t.left),i=Math.min(e.bottom,t.bottom)-Math.max(e.top,t.top);return Math.max(0,r)*Math.max(0,i)/n}(function restingRect(e,t){if(!t)return e.getBoundingClientRect();const n=e.style.animationName;e.style.animationName="none";const r=e.getBoundingClientRect();return e.style.animationName=n,r}(e,g.current),o);if(t>0&&t>=a){if(d(),i)for(const e of n)e.disconnect()}else i||m(!1)},s=function measureSteps(e){const t=Array.from({length:21},(e,t)=>t/20);return e>0&&e<1?[...t,e]:t}(a);if(r){const e=new IntersectionObserver(([e])=>{o=function clipRect(e){const t=e.boundingClientRect;return t.width*t.height>0?e.intersectionRect:e.rootBounds??viewportRect()}(e),check()},{threshold:s});n.push(e),e.observe(r)}const l=new IntersectionObserver(check,{threshold:s});return n.push(l),l.observe(e),()=>{for(const e of n)e.disconnect()}},[t,i,a,d]);const h=e.useRef(l);e.useEffect(()=>{Object.is(l,h.current)||(h.current=l,d())},[l,d]),e.useEffect(()=>{"manual"===t&&(r?d():m(!1))},[t,r,d]);const y="hover"===t?{onPointerEnter:d,onFocus:e=>{holds(c.current,e.relatedTarget)||d()},onPointerLeave:()=>{s&&m(!1)},onBlur:e=>{s&&!holds(c.current,e.relatedTarget)&&m(!1)}}:{};return{ref:e.useCallback(e=>{c.current=e},[]),state:u&&!o?"running":"paused",started:u,runs:p,handlers:y}}export function staggerSlots(e,{index:t,count:n,stagger:r,durationStep:i,reverse:a}){const o=a?n-1-t:t;return{...e,delay:e.delay+o*r,duration:Math.max(0,e.duration+o*i)}}export function animateChildren(n,r,i){const a=e.Children.toArray(n);return a.map((n,o)=>{const s=i(o,a.length);if(!e.isValidElement(n))return e.createElement("span",{key:o,className:r,style:s},n);const l=n.props;return e.cloneElement(n,{className:t(r,l.className),style:{...s,...l.style}})})}export function useAnimateElement(e){const{effect:t,trigger:n,play:r,once:i,threshold:a,paused:o,infinite:s,nonce:l,stagger:c=0,durationStep:u=0,reverse:m=!1,origin:p,children:f,...d}=e,g=useAnimationRun({trigger:"view"===d.timeline?"mount":n,play:r,once:i,threshold:a,paused:o,infinite:s,nonce:l}),h=t?`plass-anim ${animationClasses[t]}`:"",y=0!==c&&null!==t,v=void 0===p?null:{transformOrigin:p};return{ref:g.ref,className:y?"":h,style:{...v,...y?null:animationSlots(d),"--p-anim-state":g.state},props:{...g.handlers,"data-plass-animation":t??void 0,"data-state":g.state},children:y?animateChildren(f,h,(e,t)=>({...v,...animationSlots(staggerSlots(d,{index:e,count:t,stagger:c,durationStep:u,reverse:m}))})):f}}
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as o from"react";import{defaultLabels as r,useLabels as s}from"./labels.js";import{PlButton as n}from"../components/button/PlButton.js";import{ChevronIcon as l}from"./icons.js";import{dateFormatter as a}from"./format.js";import{addDays as i,addMonths as c,addYears as u,calendarWeeks as d,compareDay as m,isDayOutside as h,isMonthBeforeYear as p,isMonthOutside as g,isSameDay as f,isSameMonth as v,isValidDate as b,isYearOutside as x,makeDate as w,meridiemLabels as y,monthLabels as D,startOfDay as N,startOfMonth as S,today as C,weekdayLabels as M,withTime as k,YEAR_PAGE_SIZE as P,yearPageStart as z}from"./date.js";import{controlHeightClasses as Y,controlTextClasses as j,cx as A,gapClasses as F,metaTextClasses as E,srOnlyClasses as R,transitionClasses as H}from"./styles.js";export const defaultPickerLabels=r;export function usePickerLabels(e){const t=s();return o.useMemo(()=>e?{...t,...e}:t,[t,e])}const T={year:0,month:1,day:2},B={xs:"1.5rem",sm:"2rem",md:"2.5rem",lg:"3rem",xl:"3.5rem"},G={xs:"rounded-(--plass-radius-xs)",sm:"rounded-(--plass-radius-xs)",md:"rounded-(--plass-radius-sm)",lg:"rounded-(--plass-radius-md)",xl:"rounded-(--plass-radius-lg)"},K={xs:"rounded-s-(--plass-radius-xs)",sm:"rounded-s-(--plass-radius-xs)",md:"rounded-s-(--plass-radius-sm)",lg:"rounded-s-(--plass-radius-md)",xl:"rounded-s-(--plass-radius-lg)"},L={xs:"rounded-e-(--plass-radius-xs)",sm:"rounded-e-(--plass-radius-xs)",md:"rounded-e-(--plass-radius-sm)",lg:"rounded-e-(--plass-radius-md)",xl:"rounded-e-(--plass-radius-lg)"},I=/* @__PURE__ */["relative flex items-center justify-center tabular-nums select-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",H,"focus-visible:z-10 focus-visible:[outline:2px_solid_var(--p-ring)]","focus-visible:[outline-offset:-2px]"].join(" ");function Cell({children:o,label:r,selected:s,inRange:n=!1,rangeEdge:l=null,current:a=!1,muted:i=!1,disabled:c=!1,focused:u=!1,size:d,className:m,onClick:h,onPointerEnter:p,onKeyDown:g}){return t("button",{type:"button",role:"gridcell","aria-label":r,"aria-selected":s,"aria-current":a?"date":void 0,"aria-disabled":c||void 0,tabIndex:u?0:-1,"data-focus-target":u?"true":void 0,className:A(I,"start"===l?K[d]:"end"===l?L[d]:"middle"===l?"rounded-none":G[d],c?"cursor-not-allowed text-(--plass-muted-fg) opacity-50":s?"cursor-pointer font-semibold text-(--p-on-solid) [background-image:var(--p-fill)] hover:brightness-105 active:brightness-95":n?"cursor-pointer bg-(--p-soft) text-(--plass-fg) hover:bg-(--p-soft-hover) active:bg-(--p-soft-press)":a?"cursor-pointer font-semibold text-(--p-accent) hover:bg-(--p-soft) active:bg-(--p-soft-hover)":i?"cursor-pointer text-(--plass-muted-fg) hover:bg-(--p-soft) active:bg-(--p-soft-hover)":"cursor-pointer text-(--plass-fg) hover:bg-(--p-soft) active:bg-(--p-soft-hover)",m),onClick:()=>{c||h()},onPointerEnter:p,onKeyDown:g,children:[o,a?e("span",{"aria-hidden":"true",className:"absolute bottom-[0.18em] size-[0.22em] rounded-full bg-current"}):null]})}function Header({size:r,color:s,view:a,precision:i,month:c,locale:u,labels:d,showPreviousButton:m,showNextButton:h,onStep:g,onViewChange:f}){const v=D(u,"long")[c.getMonth()],b=String(c.getFullYear()),x=p(u),w="day"===a?[d.previousMonth,d.nextMonth]:"month"===a?[d.previousYear,d.nextYear]:[d.previousYears,d.nextYears],stepper=(t,o)=>o?e(n,{variant:"ghost",size:r,color:s,density:"compact","aria-label":w[-1===t?0:1],onClick:()=>g(t),startIcon:e("span",{className:A("flex items-center",-1===t?"rotate-90 rtl:-rotate-90":"-rotate-90 rtl:rotate-90"),children:e(l,{})})}):e("span",{"aria-hidden":"true",className:A(Y[r],"w-(--p-cell)")}),disclosure=t=>e("span",{className:A("flex items-center text-(--plass-muted-fg)","[transition:rotate_var(--plass-duration)_var(--plass-ease)]",t&&"rotate-180"),children:e(l,{})}),y=e(n,{variant:"ghost",size:r,color:s,density:"compact","aria-label":d.chooseMonth,"aria-expanded":"month"===a,onClick:()=>f("month"===a?i:"month"),endIcon:disclosure("month"===a),children:v},"month"),N=e(n,{variant:"ghost",size:r,color:s,density:"compact",className:"tabular-nums","aria-label":d.chooseYear,"aria-expanded":"year"===a,onClick:()=>f("year"===a?i:"year"),endIcon:disclosure("year"===a),children:b},"year"),S=z(c.getFullYear());return t("div",{className:"flex items-center justify-between gap-1",children:[stepper(-1,m),e("div",{className:A("flex min-w-0 flex-1 items-center justify-center",F[r]),children:"year"===a?e("span",{className:A("flex items-center font-semibold tabular-nums text-(--plass-fg)",Y[r],j[r]),children:`${S}–${S+P-1}`}):"month"===a?N:t(o.Fragment,x?{children:[y,N]}:{children:[N,y]})}),stepper(1,h)]})}export function Calendar({size:r,color:s,locale:n,weekStartsOn:l,month:a,onMonthChange:i,precision:d="day",selected:m,rangeStart:p=null,rangeEnd:g=null,onSelect:f,onPreviewChange:x,minDate:y,maxDate:D,shouldDisableDate:M,showOutsideDays:k=!0,autoFocus:z=!1,showPreviousButton:Y=!0,showNextButton:j=!0,labels:E,className:R}){const[H,G]=o.useState(d),K=T[H]>T[d]?d:H,L=o.useMemo(()=>m.filter(b),[m]),[I,O]=o.useState(()=>{const e=L.find(e=>v(e,a));return e?N(e):v(C(),a)?C():S(a)}),U=o.useRef(z),q=o.useRef(null);o.useEffect(()=>{O(e=>v(e,a)?e:S(a))},[a]),o.useLayoutEffect(()=>{U.current&&(U.current=!1,q.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const $=o.useCallback(e=>h(e,y,D)||(M?.(e)??!1),[y,D,M]),changeView=e=>{U.current=!0,G(e)},moveCursor=e=>{U.current=!0,i(e)};return t("div",{ref:q,className:A("flex flex-col",F[r],R),style:{"--p-cell":B[r]},onPointerLeave:()=>x?.(null),children:[e(Header,{size:r,color:s,view:K,precision:d,month:a,locale:n,labels:E,showPreviousButton:Y,showNextButton:j,onStep:e=>{i("day"===K?c(a,e):u(a,"month"===K?e:e*P))},onViewChange:changeView}),e("div",{className:"h-[calc(var(--p-cell)*7)] w-[calc(var(--p-cell)*7)]",children:"day"===K?e(DayGrid,{size:r,locale:n,weekStartsOn:l,month:a,chosen:L,rangeStart:p,rangeEnd:g,focusedDate:I,showOutsideDays:k,isDisabled:$,onSelect:e=>{O(e),f(e)},onPreviewChange:x,onMoveFocus:e=>{U.current=!0,O(e),v(e,a)||i(S(e))}}):"month"===K?e(MonthGrid,{size:r,locale:n,month:a,chosen:L,minDate:y,maxDate:D,onMoveCursor:moveCursor,onPick:e=>{const t=w(a.getFullYear(),e,1);i(t),"month"===d?f(t):changeView("day")}}):e(YearGrid,{size:r,month:a,chosen:L,minDate:y,maxDate:D,onMoveCursor:moveCursor,onPick:e=>{const t=w(e,"year"===d?0:a.getMonth(),1);i(t),"year"===d?f(t):changeView("month")}})})]})}function DayGrid({size:o,locale:r,weekStartsOn:s,month:n,chosen:l,rangeStart:u,rangeEnd:h,focusedDate:p,showOutsideDays:g,isDisabled:x,onSelect:w,onPreviewChange:y,onMoveFocus:D}){const N=d(n,s),S=M(r,s,"short"),k=M(r,s,"long"),P=a(r,{dateStyle:"full"}),z=function orderedRange(e,t){return b(e)&&b(t)?m(e,t)<=0?[e,t]:[t,e]:null}(u,h),Y=C();return t("div",{role:"grid",className:"flex h-full flex-col",children:[e("div",{role:"row",className:"grid grid-cols-7",children:S.map((t,r)=>e("span",{role:"columnheader","aria-label":k[r],className:A("flex h-(--p-cell) items-center justify-center font-semibold text-(--plass-muted-fg) select-none",E[o]),children:t},r))}),N.map((t,r)=>e("div",{role:"row",className:"grid grid-cols-7",children:t.map(t=>{const r=!v(t,n);if(r&&!g)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--p-cell)"},t.getTime());const a=l.some(e=>f(e,t)),u=null!==z&&m(t,z[0])>=0&&m(t,z[1])<=0,d=null!==z&&u&&f(t,z[0]),h=null!==z&&u&&f(t,z[1]);return e(Cell,{size:o,label:P.format(t),selected:a,inRange:u&&!a,rangeEdge:u?d&&h?"both":d?"start":h?"end":"middle":null,current:f(t,Y)&&!a,muted:r,disabled:x(t),focused:f(t,p),className:A("size-(--p-cell)",j[o]),onClick:()=>w(t),onPointerEnter:()=>y?.(t),onKeyDown:e=>((e,t)=>{const o=(t.getDay()-s+7)%7,r={ArrowLeft:()=>i(t,-1),ArrowRight:()=>i(t,1),ArrowUp:()=>i(t,-7),ArrowDown:()=>i(t,7),Home:()=>i(t,-o),End:()=>i(t,6-o),PageUp:()=>c(t,e.shiftKey?-12:-1),PageDown:()=>c(t,e.shiftKey?12:1)}[e.key];r&&(e.preventDefault(),D(r()))})(e,t),children:t.getDate()},t.getTime())})},r))]})}function MonthGrid({size:t,locale:o,month:r,chosen:s,minDate:n,maxDate:l,onMoveCursor:a,onPick:i}){const u=D(o,"short"),d=D(o,"long"),m=r.getFullYear(),h=new Date,onKeyDown=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==t&&(e.preventDefault(),a(c(S(r),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(o=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(a=>{const c=3*o+a;return e(Cell,{size:t,label:`${d[c]} ${m}`,selected:s.some(e=>e.getFullYear()===m&&e.getMonth()===c),current:h.getFullYear()===m&&h.getMonth()===c,disabled:g(w(m,c,1),n,l),focused:c===r.getMonth(),className:A("h-(--p-cell) w-full",j[t]),onClick:()=>i(c),onKeyDown,children:u[c]},c)})},o))})}function YearGrid({size:t,month:o,chosen:r,minDate:s,maxDate:n,onMoveCursor:l,onPick:a}){const i=z(o.getFullYear()),c=(new Date).getFullYear(),onKeyDown=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-P,PageDown:P}[e.key];void 0!==t&&(e.preventDefault(),l(u(S(o),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(l=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(u=>{const d=i+4*l+u;return e(Cell,{size:t,label:String(d),selected:r.some(e=>e.getFullYear()===d),current:d===c,disabled:x(w(d,0,1),s,n),focused:d===o.getFullYear(),className:A("h-(--p-cell) w-full",j[t]),onClick:()=>a(d),onKeyDown,children:d},d)})},l))})}function revealInColumn(e){const t=e.parentElement;if(!t)return;const o=e.getBoundingClientRect(),r=t.getBoundingClientRect(),s=o.top-r.top-t.clientTop+t.scrollTop,n=s+o.height;s<t.scrollTop?t.scrollTop=s:n>t.scrollTop+t.clientHeight&&(t.scrollTop=n-t.clientHeight)}export function TimeGrid({size:r,density:s,locale:n,value:l,referenceDate:i,onChange:c,hour12:u,showSeconds:d,hourStep:m,minuteStep:h,secondStep:p,shouldDisableTime:g,autoFocus:f=!1,labels:v,className:b}){const x=l??i,w=o.useRef(null),[D,N]=o.useMemo(()=>y(n),[n]);o.useEffect(()=>{const e=w.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(revealInColumn),f){const t=e?.querySelector('[role="listbox"]');(t?.querySelector('[data-chosen="true"]')??t?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[f]);const S=o.useMemo(()=>{const e=Math.ceil((u?12:24)/m),t=Array.from({length:e},(e,t)=>t*m);return u?t.map(e=>0===e?12:e):t},[u,m]),C=o.useMemo(()=>Array.from({length:Math.ceil(60/h)},(e,t)=>t*h),[h]),M=o.useMemo(()=>Array.from({length:Math.ceil(60/p)},(e,t)=>t*p),[p]),pad=e=>String(e).padStart(2,"0"),P=u?x.getHours()%12||12:x.getHours(),column=(t,o,s,n,a)=>e("div",{role:"listbox","aria-label":o,className:A("flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--p-cell)*7)] w-[calc(var(--p-cell)*1.75)]","scroll-py-0.5 [scrollbar-width:thin]"),children:s.map(o=>{const s=((e,t)=>k(x,"hour"===e?{hours:u?t%12+(x.getHours()>=12?12:0):t}:"minute"===e?{minutes:t}:"second"===e?{seconds:t}:{hours:x.getHours()%12+12*t}))(t,o),i=null!==l&&n(o),d=g?.(s,t)??!1;return e("button",{type:"button",role:"option","aria-selected":i,"aria-disabled":d||void 0,"data-chosen":i?"true":void 0,className:A(I,G[r],Y[r],j[r],"w-full shrink-0",d?"cursor-not-allowed text-(--plass-muted-fg) opacity-50":i?"cursor-pointer font-semibold text-(--p-on-solid) [background-image:var(--p-fill)] hover:brightness-105 active:brightness-95":"cursor-pointer text-(--plass-fg) hover:bg-(--p-soft) active:bg-(--p-soft-hover)"),onClick:()=>{d||c(s)},children:a(o)},o)})},t);return t("div",{ref:w,className:A("flex","compact"===s?"gap-0.5":"gap-1",b),style:{"--p-cell":B[r]},children:[column("hour",v.hour,S,e=>e===P,e=>u?String(e):pad(e)),column("minute",v.minute,C,e=>e===x.getMinutes(),pad),d?column("second",v.second,M,e=>e===x.getSeconds(),pad):null,u?column("meridiem",v.meridiem,[0,1],e=>(x.getHours()>=12?1:0)===e,e=>0===e?D:N):null,e("span",{className:R,"aria-live":"polite",children:null===l?"":a(n,{hour:"numeric",minute:"2-digit",...d?{second:"2-digit"}:{}}).format(l)})]})}
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as o from"react";import{defaultLabels as t,useLabels as n}from"./labels.js";import{PlButton as l}from"../components/button/PlButton.js";import{ChevronIcon as s}from"./icons.js";import{dateFormatter as a}from"./format.js";import{addDays as i,addMonths as c,addYears as d,calendarWeeks as u,compareDay as m,isDayOutside as h,isMonthBeforeYear as p,isMonthOutside as g,isSameDay as f,isSameMonth as b,isValidDate as v,isYearOutside as y,makeDate as x,meridiemLabels as w,monthLabels as D,startOfDay as N,startOfMonth as S,today as k,weekdayLabels as C,withTime as M,YEAR_PAGE_SIZE as P,yearPageStart as z}from"./date.js";import{controlHeightClasses as A,controlTextClasses as $,cx as Y,forcedFillClasses as j,gapClasses as B,metaTextClasses as E,srOnlyClasses as F,transitionClasses as I}from"./styles.js";export const defaultPickerLabels=t;export function usePickerLabels(e){const r=n();return o.useMemo(()=>e?{...r,...e}:r,[r,e])}const H={year:0,month:1,day:2},T={xs:"1.5rem",sm:"2rem",md:"2.5rem",lg:"3rem",xl:"3.5rem"},R={xs:"rounded-(--plass-radius-xs)",sm:"rounded-(--plass-radius-xs)",md:"rounded-(--plass-radius-sm)",lg:"rounded-(--plass-radius-md)",xl:"rounded-(--plass-radius-lg)"},K={xs:"rounded-s-(--plass-radius-xs)",sm:"rounded-s-(--plass-radius-xs)",md:"rounded-s-(--plass-radius-sm)",lg:"rounded-s-(--plass-radius-md)",xl:"rounded-s-(--plass-radius-lg)"},O={xs:"rounded-e-(--plass-radius-xs)",sm:"rounded-e-(--plass-radius-xs)",md:"rounded-e-(--plass-radius-sm)",lg:"rounded-e-(--plass-radius-md)",xl:"rounded-e-(--plass-radius-lg)"},G=/* @__PURE__ */["relative flex items-center justify-center tabular-nums select-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",I,"focus-visible:z-10 focus-visible:[outline:2px_solid_var(--p-ring)]","focus-visible:[outline-offset:-2px]"].join(" ");function Cell({children:o,label:t,selected:n,inRange:l=!1,rangeEdge:s=null,current:a=!1,muted:i=!1,disabled:c=!1,focused:d=!1,size:u,className:m,onClick:h,onPointerEnter:p,onKeyDown:g}){return r("button",{type:"button",role:"gridcell","aria-label":t,"aria-selected":n,"aria-current":a?"date":void 0,"aria-disabled":c||void 0,tabIndex:d?0:-1,"data-focus-target":d?"true":void 0,className:Y(G,"start"===s?K[u]:"end"===s?O[u]:"middle"===s?"rounded-none":R[u],c?"cursor-not-allowed text-(--plass-muted-fg) opacity-50":n?`cursor-pointer font-semibold text-(--p-on-solid) [background-image:var(--p-fill)] hover:brightness-105 active:brightness-95 ${j}`:l?"cursor-pointer bg-(--p-soft) text-(--plass-fg) hover:bg-(--p-soft-hover) active:bg-(--p-soft-press) forced-colors:border-y forced-colors:[border-color:Highlight]":a?"cursor-pointer font-semibold text-(--p-accent) hover:bg-(--p-soft) active:bg-(--p-soft-hover)":i?"cursor-pointer text-(--plass-muted-fg) hover:bg-(--p-soft) active:bg-(--p-soft-hover)":"cursor-pointer text-(--plass-fg) hover:bg-(--p-soft) active:bg-(--p-soft-hover)",m),onClick:()=>{c||h()},onPointerEnter:p,onKeyDown:g,children:[o,a?e("span",{"aria-hidden":"true",className:Y("absolute bottom-[0.18em] size-[0.22em] rounded-full bg-current",n?"forced-colors:[background-color:HighlightText]":"forced-colors:[background-color:CanvasText]")}):null]})}function headingIds(e,r,o){return"year"===r?`${e}-range`:"month"===r?`${e}-year`:p(o)?`${e}-month ${e}-year`:`${e}-year ${e}-month`}function Header({size:t,color:n,view:a,precision:i,month:c,locale:d,labels:u,showPreviousButton:m,showNextButton:h,onStep:g,onViewChange:f,id:b}){const v=D(d,"long")[c.getMonth()],y=String(c.getFullYear()),x=p(d),w="day"===a?[u.previousMonth,u.nextMonth]:"month"===a?[u.previousYear,u.nextYear]:[u.previousYears,u.nextYears],stepper=(r,o)=>o?e(l,{variant:"ghost",size:t,color:n,density:"compact","aria-label":w[-1===r?0:1],onClick:()=>g(r),startIcon:e("span",{className:Y("flex items-center",-1===r?"rotate-90 rtl:-rotate-90":"-rotate-90 rtl:rotate-90"),children:e(s,{})})}):e("span",{"aria-hidden":"true",className:Y(A[t],"w-(--p-cell)")}),disclosure=r=>e("span",{className:Y("flex items-center text-(--plass-muted-fg)","[transition:rotate_var(--plass-duration)_var(--plass-ease)]",r&&"rotate-180"),children:e(s,{})}),N=e(l,{id:`${b}-month`,variant:"ghost",size:t,color:n,density:"compact","aria-describedby":`${b}-month-hint`,"aria-expanded":"month"===a,onClick:()=>f("month"===a?i:"month"),endIcon:disclosure("month"===a),children:v},"month"),S=e(l,{id:`${b}-year`,variant:"ghost",size:t,color:n,density:"compact",className:"tabular-nums","aria-describedby":`${b}-year-hint`,"aria-expanded":"year"===a,onClick:()=>f("year"===a?i:"year"),endIcon:disclosure("year"===a),children:y},"year"),k=z(c.getFullYear());return r("div",{className:"flex items-center justify-between gap-1",children:[stepper(-1,m),e("div",{className:Y("flex min-w-0 flex-1 items-center justify-center",B[t]),children:"year"===a?e("span",{id:`${b}-range`,className:Y("flex items-center font-semibold tabular-nums text-(--plass-fg)",A[t],$[t]),children:`${k}–${k+P-1}`}):"month"===a?S:r(o.Fragment,x?{children:[N,S]}:{children:[S,N]})}),stepper(1,h),e("span",{id:`${b}-month-hint`,hidden:!0,children:u.chooseMonth}),e("span",{id:`${b}-year-hint`,hidden:!0,children:u.chooseYear})]})}export function Calendar({size:t,color:n,locale:l,weekStartsOn:s,month:a,onMonthChange:i,precision:u="day",selected:m,rangeStart:p=null,rangeEnd:g=null,onSelect:f,onPreviewChange:y,minDate:w,maxDate:D,shouldDisableDate:C,showOutsideDays:M=!0,autoFocus:z=!1,showPreviousButton:A=!0,showNextButton:$=!0,labels:j,className:E}){const F=o.useId(),[I,R]=o.useState(u),K=H[I]>H[u]?u:I,O=o.useMemo(()=>m.filter(v),[m]),[G,L]=o.useState(()=>{const e=O.find(e=>b(e,a));return e?N(e):b(k(),a)?k():S(a)}),U=o.useRef(z),q=o.useRef(null);o.useEffect(()=>{L(e=>b(e,a)?e:S(a))},[a]),o.useLayoutEffect(()=>{U.current&&(U.current=!1,q.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const _=o.useCallback(e=>h(e,w,D)||(C?.(e)??!1),[w,D,C]),changeView=e=>{U.current=!0,R(e)},moveCursor=e=>{U.current=!0,i(e)};return r("div",{ref:q,className:Y("flex flex-col",B[t],E),style:{"--p-cell":T[t]},onPointerLeave:()=>y?.(null),children:[e(Header,{size:t,color:n,view:K,precision:u,month:a,locale:l,labels:j,showPreviousButton:A,showNextButton:$,onStep:e=>{i("day"===K?c(a,e):d(a,"month"===K?e:e*P))},onViewChange:changeView,id:F}),e("div",{className:"h-[calc(var(--p-cell)*7)] w-[calc(var(--p-cell)*7)]",children:"day"===K?e(DayGrid,{labelledBy:headingIds(F,K,l),size:t,locale:l,weekStartsOn:s,month:a,chosen:O,rangeStart:p,rangeEnd:g,focusedDate:G,showOutsideDays:M,isDisabled:_,onSelect:e=>{L(e),f(e)},onPreviewChange:y,onMoveFocus:e=>{U.current=!0,L(e),b(e,a)||i(S(e))}}):"month"===K?e(MonthGrid,{labelledBy:headingIds(F,K,l),size:t,locale:l,month:a,chosen:O,minDate:w,maxDate:D,onMoveCursor:moveCursor,onPick:e=>{const r=x(a.getFullYear(),e,1);i(r),"month"===u?f(r):changeView("day")}}):e(YearGrid,{labelledBy:headingIds(F,K,l),size:t,month:a,chosen:O,minDate:w,maxDate:D,onMoveCursor:moveCursor,onPick:e=>{const r=x(e,"year"===u?0:a.getMonth(),1);i(r),"year"===u?f(r):changeView("month")}})})]})}function DayGrid({labelledBy:o,size:t,locale:n,weekStartsOn:l,month:s,chosen:d,rangeStart:h,rangeEnd:p,focusedDate:g,showOutsideDays:y,isDisabled:x,onSelect:w,onPreviewChange:D,onMoveFocus:N}){const S=u(s,l),M=C(n,l,"short"),P=C(n,l,"long"),z=a(n,{dateStyle:"full"}),A=function orderedRange(e,r){return v(e)&&v(r)?m(e,r)<=0?[e,r]:[r,e]:null}(h,p),j=k();return r("div",{role:"grid","aria-labelledby":o,className:"flex h-full flex-col",children:[e("div",{role:"row",className:"grid grid-cols-7",children:M.map((r,o)=>e("span",{role:"columnheader","aria-label":P[o],className:Y("flex h-(--p-cell) items-center justify-center font-semibold text-(--plass-muted-fg) select-none",E[t]),children:r},o))}),S.map((r,o)=>e("div",{role:"row",className:"grid grid-cols-7",children:r.map(r=>{const o=!b(r,s);if(o&&!y)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--p-cell)"},r.getTime());const n=d.some(e=>f(e,r)),a=null!==A&&m(r,A[0])>=0&&m(r,A[1])<=0,u=null!==A&&a&&f(r,A[0]),h=null!==A&&a&&f(r,A[1]);return e(Cell,{size:t,label:z.format(r),selected:n,inRange:a&&!n,rangeEdge:a?u&&h?"both":u?"start":h?"end":"middle":null,current:f(r,j)&&!n,muted:o,disabled:x(r),focused:f(r,g),className:Y("size-(--p-cell)",$[t]),onClick:()=>w(r),onPointerEnter:()=>D?.(r),onKeyDown:e=>((e,r)=>{const o=(r.getDay()-l+7)%7,t={ArrowLeft:()=>i(r,-1),ArrowRight:()=>i(r,1),ArrowUp:()=>i(r,-7),ArrowDown:()=>i(r,7),Home:()=>i(r,-o),End:()=>i(r,6-o),PageUp:()=>c(r,e.shiftKey?-12:-1),PageDown:()=>c(r,e.shiftKey?12:1)}[e.key];t&&(e.preventDefault(),N(t()))})(e,r),children:r.getDate()},r.getTime())})},o))]})}function MonthGrid({labelledBy:r,size:o,locale:t,month:n,chosen:l,minDate:s,maxDate:a,onMoveCursor:i,onPick:d}){const u=D(t,"short"),m=D(t,"long"),h=n.getFullYear(),p=new Date,onKeyDown=e=>{const r={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==r&&(e.preventDefault(),i(c(S(n),r)))};return e("div",{role:"grid","aria-labelledby":r,className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(r=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(t=>{const i=3*r+t;return e(Cell,{size:o,label:`${m[i]} ${h}`,selected:l.some(e=>e.getFullYear()===h&&e.getMonth()===i),current:p.getFullYear()===h&&p.getMonth()===i,disabled:g(x(h,i,1),s,a),focused:i===n.getMonth(),className:Y("h-(--p-cell) w-full",$[o]),onClick:()=>d(i),onKeyDown,children:u[i]},i)})},r))})}function YearGrid({labelledBy:r,size:o,month:t,chosen:n,minDate:l,maxDate:s,onMoveCursor:a,onPick:i}){const c=z(t.getFullYear()),u=(new Date).getFullYear(),onKeyDown=e=>{const r={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-P,PageDown:P}[e.key];void 0!==r&&(e.preventDefault(),a(d(S(t),r)))};return e("div",{role:"grid","aria-labelledby":r,className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(r=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(a=>{const d=c+4*r+a;return e(Cell,{size:o,label:String(d),selected:n.some(e=>e.getFullYear()===d),current:d===u,disabled:y(x(d,0,1),l,s),focused:d===t.getFullYear(),className:Y("h-(--p-cell) w-full",$[o]),onClick:()=>i(d),onKeyDown,children:d},d)})},r))})}function revealInColumn(e){const r=e.parentElement;if(!r)return;const o=e.getBoundingClientRect(),t=r.getBoundingClientRect(),n=o.top-t.top-r.clientTop+r.scrollTop,l=n+o.height;n<r.scrollTop?r.scrollTop=n:l>r.scrollTop+r.clientHeight&&(r.scrollTop=l-r.clientHeight)}export function TimeGrid({size:t,density:n,locale:l,value:s,referenceDate:i,onChange:c,hour12:d,showSeconds:u,hourStep:m,minuteStep:h,secondStep:p,shouldDisableTime:g,autoFocus:f=!1,labels:b,className:v}){const y=s??i,x=o.useRef(null),[D,N]=o.useMemo(()=>w(l),[l]);o.useEffect(()=>{const e=x.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(revealInColumn),f){const r=e?.querySelector('[role="listbox"]');(r?.querySelector('[data-chosen="true"]')??r?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[f]);const S=o.useMemo(()=>{const e=Math.ceil((d?12:24)/m),r=Array.from({length:e},(e,r)=>r*m);return d?r.map(e=>0===e?12:e):r},[d,m]),k=o.useMemo(()=>Array.from({length:Math.ceil(60/h)},(e,r)=>r*h),[h]),C=o.useMemo(()=>Array.from({length:Math.ceil(60/p)},(e,r)=>r*p),[p]),candidate=(e,r)=>M(y,"hour"===e?{hours:d?r%12+(y.getHours()>=12?12:0):r}:"minute"===e?{minutes:r}:"second"===e?{seconds:r}:{hours:y.getHours()%12+12*r}),pad=e=>String(e).padStart(2,"0"),P=d?y.getHours()%12||12:y.getHours(),column=(r,o,n,l,a)=>{const i=n.map(e=>g?.(candidate(r,e),r)??!1),d=null===s?-1:n.findIndex(l),u=d>=0?d:Math.max(0,i.indexOf(!1)),nearest=(e,r)=>{for(let o=e;o>=0&&o<n.length;o+=r)if(!i[o])return o;return-1};return e("div",{role:"listbox","aria-label":o,onKeyDown:e=>{const o=[...e.currentTarget.querySelectorAll('[role="option"]')],t=o.indexOf(e.target);if(t<0)return;const l="ArrowDown"===e.key?nearest(t+1,1):"ArrowUp"===e.key?nearest(t-1,-1):"Home"===e.key?nearest(0,1):"End"===e.key?nearest(n.length-1,-1):null;null!==l&&(e.preventDefault(),l<0||l===t||(c(candidate(r,n[l])),o[l].focus({preventScroll:!0}),revealInColumn(o[l])))},className:Y("flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--p-cell)*7)] w-[calc(var(--p-cell)*1.75)]","scroll-py-0.5 [scrollbar-width:thin]"),children:n.map((o,n)=>{const d=candidate(r,o),m=null!==s&&l(o),h=i[n];return e("button",{type:"button",role:"option",tabIndex:n===u?0:-1,"aria-selected":m,"aria-disabled":h||void 0,"data-chosen":m?"true":void 0,className:Y(G,R[t],A[t],$[t],"w-full shrink-0",h?"cursor-not-allowed text-(--plass-muted-fg) opacity-50":m?`cursor-pointer font-semibold text-(--p-on-solid) [background-image:var(--p-fill)] hover:brightness-105 active:brightness-95 ${j}`:"cursor-pointer text-(--plass-fg) hover:bg-(--p-soft) active:bg-(--p-soft-hover)"),onClick:()=>{h||c(d)},children:a(o)},o)})},r)};return r("div",{ref:x,className:Y("flex","compact"===n?"gap-0.5":"gap-1",v),style:{"--p-cell":T[t]},children:[column("hour",b.hour,S,e=>e===P,e=>d?String(e):pad(e)),column("minute",b.minute,k,e=>e===y.getMinutes(),pad),u?column("second",b.second,C,e=>e===y.getSeconds(),pad):null,d?column("meridiem",b.meridiem,[0,1],e=>(y.getHours()>=12?1:0)===e,e=>0===e?D:N):null,e("span",{className:F,"aria-live":"polite",children:null===s?"":a(l,{hour:"numeric",minute:"2-digit",...u?{second:"2-digit"}:{}}).format(s)})]})}
@@ -261,20 +261,7 @@ interface DataTableProps {
261
261
  format: (value: number) => string;
262
262
  locale?: string;
263
263
  }
264
- /**
265
- * The chart, as a table, for the readers a drawing does not reach.
266
- *
267
- * Not an option and not a toggle. A tooltip that is the only way to a number
268
- * gates that number behind a pointer, and an SVG with an `aria-label` on it
269
- * says "revenue by month" and then says nothing else at all. This is the same
270
- * data in the one form every assistive technology already reads, so the picture
271
- * is free to be a picture.
272
- *
273
- * It is clipped rather than `display: none`, for the reason `srOnlyClasses`
274
- * gives: the second one takes it off the accessibility tree along with the
275
- * screen, which would leave the chart exactly as mute as before.
276
- */
277
- declare function ChartDataTable({ id, caption, corner, categories, series, values, format, locale }: DataTableProps): React.JSX.Element;
264
+ declare const ChartDataTable: React.MemoExoticComponent<({ id, caption, corner, categories, series, values, format, locale }: DataTableProps) => React.JSX.Element>;
278
265
  interface SurfaceProps extends Omit<PlBoxProps, 'children'> {
279
266
  legend: React.ReactNode;
280
267
  legendSide: NonNullable<PlassChartLegend['side']>;
@@ -330,6 +317,8 @@ export interface CartesianLayout {
330
317
  visible: readonly boolean[];
331
318
  /** And what colour each one is, by its original index. */
332
319
  colors: readonly string[];
320
+ /** Which of them are drawn as a dashed line, in the same order. */
321
+ dashed: readonly boolean[];
333
322
  scale: ValueScale;
334
323
  band: BandScale;
335
324
  /** Bars run along the category axis rather than across it. */
@@ -1 +1 @@
1
- "use client";import{jsx as e,Fragment as t,jsxs as l}from"react/jsx-runtime";import*as a from"react";import{PlBox as n}from"../components/box/PlBox.js";import{bandScale as s,categoryAt as i,categoryCount as r,categoryExtent as o,chartFontSizes as c,compactNumber as d,extentOf as h,fitsLast as u,formatCategory as m,markerRadii as p,plotHeights as f,seriesColor as x,showsTick as g,textWidth as v,tickStride as b,toValues as y,truncate as k,valueScale as w}from"./chart.js";import{useDefaults as M}from"./defaults.js";import{numberFormatter as C}from"./format.js";import{usePlElementSize as N}from"../hooks/usePlElementSize.js";import{useLabels as S}from"./labels.js";import{cx as z,glassClasses as P,hasContent as A,metaTextClasses as j,srOnlyClasses as B,transitionClasses as T}from"./styles.js";const W=[];function useMeasuredWidth(e){return N(e)?.width??0}export const markTransitionClasses=["[transition:opacity_var(--plass-duration)_var(--plass-ease),","r_var(--plass-duration)_var(--plass-ease),","scale_var(--plass-duration)_var(--plass-ease)]"].join("");function useVisibility(e){const[t,l]=a.useState(()=>{const t=new Set;return e.forEach((e,l)=>{e.hidden&&t.add(l)}),t}),[n,s]=a.useState(null),i=a.useCallback(e=>{l(t=>{const l=new Set(t);return l.has(e)?l.delete(e):l.add(e),l})},[]);return{visible:e.map((e,l)=>!t.has(l)),hovered:n,toggle:i,setHovered:s}}const _={top:"flex-col-reverse",bottom:"flex-col",left:"flex-row-reverse",right:"flex-row"},F={start:"justify-start",center:"justify-center",end:"justify-end"};function ChartLegendBar({series:a,colors:n,options:s,visibility:i,size:r,values:o,swatch:c}){const d=!1!==s.interactive,h="left"===s.side||"right"===s.side;return e("ul",{className:z("flex list-none flex-wrap items-center gap-x-3 gap-y-1 p-0",h?"min-w-0 flex-col items-start":"",F[s.align??"center"],j[r]),children:a.map((a,s)=>{const r=i.visible[s],h=null!==i.hovered&&i.hovered!==s,u=a.name??`${s+1}`,m=r?n[s]:`color-mix(in oklab, ${n[s]} 40%, transparent)`,p=l(t,{children:[e("span",c?{"aria-hidden":"true",className:"flex size-2.5 shrink-0 items-center justify-center",children:c(s,m)}:{"aria-hidden":"true",className:`size-2.5 shrink-0 rounded-[0.1875rem] ${T}`,style:{backgroundColor:m}}),e("span",{className:"min-w-0 truncate",children:u}),o?.[s]?e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:o[s]}):null]});return e("li",{className:"min-w-0",children:d?e("button",{type:"button","aria-pressed":r,onClick:()=>i.toggle(s),onPointerEnter:()=>i.setHovered(s),onPointerLeave:()=>i.setHovered(null),onFocus:()=>i.setHovered(s),onBlur:()=>i.setHovered(null),className:z("flex min-w-0 cursor-pointer items-center gap-1.5 rounded-(--plass-radius-xs)","px-1 py-0.5 text-(--plass-fg)","[transition-property:background-color,color,opacity]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]","hover:bg-(--p-soft)","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-1",r?"":"text-(--plass-muted-fg) line-through",h?"opacity-55":""),children:p}):e("span",{className:z("flex min-w-0 items-center gap-1.5 px-1 py-0.5 text-(--plass-fg)",r?"":"text-(--plass-muted-fg) line-through"),children:p})},a.name??s)})})}function ChartScaleLegend({steps:a,from:n,to:s,middle:i,align:r,vertical:o,size:c}){return e("div",{className:z("flex",o?"":F[r]),children:l("div",{className:z("grid grid-cols-[auto_auto_auto] items-center gap-x-2",j[c]),children:[e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:n}),e("span",{"aria-hidden":"true",className:z("flex h-2.5 overflow-hidden rounded-[0.1875rem]",o?"w-20":"w-24"),children:a.map(t=>e("span",{className:"h-full flex-1",style:{backgroundColor:t}},t))}),e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:s}),i?l(t,{children:[e("span",{}),e("span",{className:"text-center tabular-nums text-(--plass-muted-fg)",children:i}),e("span",{})]}):null]})})}function ChartTooltipPanel({heading:t,items:a,x:n,y:s,flip:i,size:r}){return l("div",{"data-plass-tooltip":"",className:z("pointer-events-none absolute z-10 max-w-56 min-w-24","rounded-(--plass-radius-sm) border p-2",P,"bg-(--plass-glass-press) [border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]",j[r]),style:i?{right:`calc(100% - ${n}px + 10px)`,top:s}:{left:n+10,top:s},children:[e("div",{className:"mb-1 font-medium text-(--plass-fg)",children:t}),e("ul",{className:"flex list-none flex-col gap-0.5 p-0",children:a.map(t=>l("li",{className:"flex items-center gap-1.5",children:[e("span",{"aria-hidden":"true",className:"size-2 shrink-0 rounded-[0.125rem]",style:{backgroundColor:t.color}}),t.name?e("span",{className:"min-w-0 flex-1 truncate text-(--plass-muted-fg)",children:t.name}):null,e("span",{className:"ms-auto shrink-0 font-medium tabular-nums text-(--plass-fg)",children:t.label??t.formatted})]},t.seriesIndex))})]})}function ChartStatus({heading:n,items:s}){return e("span",{role:"status","aria-live":"polite",className:B,children:0===s.length?null:l(t,{children:[A(n)?l(t,{children:[n,", "]}):null,s.map((e,t)=>l(a.Fragment,{children:[t>0?", ":null,e.name?`${e.name}: `:null,e.label??e.formatted]},e.seriesIndex))]})})}function ChartDataTable({id:t,caption:a,corner:n,categories:s,series:i,values:r,format:o,locale:c}){return l("table",{id:t,className:B,children:[a?e("caption",{children:a}):null,e("thead",{children:l("tr",{children:[e("th",{scope:"col",children:n??""}),i.map((t,l)=>e("th",{scope:"col",children:t.name??l+1},t.name??l))]})}),e("tbody",{children:s.map((t,a)=>l("tr",{children:[e("th",{scope:"row",children:m(t,c)}),i.map((t,l)=>{const n=r[l]?.[a];return e("td",void 0!==n?.label?{children:n.label}:{children:null==n?.value?"":o(n.value)},t.name??l)})]},a))})]})}function ChartSurface({legend:t,legendSide:a,children:s,table:i,className:r,...o}){return l(n,{...o,className:z("relative flex gap-3",_[a],r??void 0),children:[e("div",{className:"relative min-w-0 flex-1",children:s}),t,i]})}export function CartesianChart({series:t,categories:n,xAxis:u,yAxis:g,horizontal:b=!1,stacked:N=!1,includeZero:P=!0,bandRatio:A=1,inset:B=!1,headroom:T=0,markInset:_=0,xScale:F="band",marks:L,markRadius:$=24,table:I,swatch:R,scale:V,markTooltip:D,height:E,format:H,locale:X,label:Y,legend:Z,tooltip:K,empty:U,size:q,variant:G="ghost",padded:J=!1,className:O,children:Q,...ee}){const te=M(),le=q??te.size??"md",ae=X??te.locale,ne=a.useRef(null),se=useMeasuredWidth(ne),ie=S(),re=a.useId(),oe=useVisibility(t),[ce,de]=a.useState(null),[he,ue]=a.useState(null),[me,pe]=a.useState(null),fe=a.useCallback(e=>H?C(ae,H).format(e):d(e,ae),[H,ae]),xe=a.useMemo(()=>y(t),[t]),ge=a.useMemo(()=>t.map((e,t)=>x(e,t)),[t]),ve=r(t),be=a.useMemo(()=>Array.from({length:ve},(e,t)=>i(t,n,xe)),[ve,n,xe]),ye=xe.filter((e,t)=>oe.visible[t]),ke=h(ye,N),we="number"==typeof E?E:void 0===E?f[le]:null,Me=c[le],Ce=g,Ne=u,Se=V??w(ke,{min:Ce?.min,max:Ce?.max,tickCount:Ce?.tickCount,includeZero:P}),ze="value"===F?o(ye,n):null,Pe="value"===F?w(ze,{min:Ne?.min,max:Ne?.max,tickCount:Ne?.tickCount,includeZero:!1}):null,Ae=Se.ticks.map((e,t)=>Ce?.tickFormat?String(Ce.tickFormat(e,t)):fe(e)),je=Pe?Pe.ticks.map((e,t)=>Ne?.tickFormat?String(Ne.tickFormat(e,t)):d(e,ae)):be.map((e,t)=>Ne?.tickFormat?String(Ne.tickFormat(e,t)):m(e,ae)),Be=Ae.reduce((e,t)=>Math.max(e,v(t,Me)),0),Te=Me+6,We=Ce?.hidden?0:Be+10+(Ce?.label?Te:0),_e=(se-(b?0:We)-16)/Math.max(1,ve),Fe=Pe?je:b||_e-6>=2.4*Me?je.map(e=>k(e,b?150:_e-6,Me)):je,Le=Fe.reduce((e,t)=>Math.max(e,v(t,Me)),0),$e=b?Ne?.hidden?0:Le+10+(Ne?.label?Te:0):We,Ie=b?Ce?.hidden?0:Me+12+(Ce?.label?Te:0):Ne?.hidden?0:Me+12+(Ne?.label?Te:0),Re=(b?Ne:Ce)?.thickness??$e,Ve=(b?Ce:Ne)?.thickness??Ie,De=(b||Pe?12:Math.max(8,Fe.length?Le/2:8))+_,Ee=p[le]+4+T+_,He=we??0,Xe={left:Re+_,top:Ee,width:Math.max(0,se-Re-_-De),height:Math.max(0,He-Ee-Ve-_)},Ye=b?Xe.height:Xe.width,Ze=s(B?Math.max(1,ve-1):ve,Ye,A),Ke=a.useCallback(e=>B?ve<=1?Ye/2:Ye*e/(ve-1):Ze.centre(e),[B,ve,Ye,Ze]),Ue=a.useCallback(e=>b?Xe.left+Se.fraction(e)*Xe.width:Xe.top+(1-Se.fraction(e))*Xe.height,[b,Xe.left,Xe.top,Xe.width,Xe.height,Se]),qe=a.useCallback((e,t)=>b?{x:Ue(t),y:Xe.top+Ke(e)}:{x:Xe.left+Ke(e),y:Ue(t)},[b,Ue,Ke,Xe.left,Xe.top]),Ge=a.useCallback(e=>b?Xe.top+(1-(Pe?.fraction(e)??0))*Xe.height:Xe.left+(Pe?.fraction(e)??0)*Xe.width,[b,Xe.left,Xe.top,Xe.width,Xe.height,Pe]),Je=Ue(Math.min(Math.max(0,Se.min),Se.max)),Oe={plot:Xe,values:xe,visible:oe.visible,colors:ge,scale:Se,band:Ze,horizontal:b,valuePx:Ue,categoryPx:Ke,point:qe,categoryScale:Pe,categoryValuePx:Ge,zeroPx:Je,categories:be,format:fe,size:le},Qe=L?L(Oe):W,et=!1===K?{mode:"none"}:!0===K||void 0===K?{}:K,tt=et.mode??(L?"item":"index"),lt=null===he?null:Qe[he]??null,at=L?lt?lt.index:null:ce,nt=L?Qe.length:ve,clearActive=()=>{de(null),ue(null),pe(null)},goTo=e=>{const t=null===e?null:Math.min(nt-1,Math.max(0,e));L?ue(t):de(t)},step=e=>{pe(null),goTo(((L?he:ce)??(e>0?-1:nt))+e)},st=null===at?[]:t.flatMap((e,t)=>{if(!oe.visible[t]||lt&&lt.series!==t)return[];const l=xe[t]?.[at];return l&&null!==l.value?[{seriesIndex:t,name:e.name,color:l.color??ge[t],value:l.value,formatted:fe(l.value),label:l.label}]:[]}),it=lt&&D?D(lt):null,rt=it?it.items:"item"===tt&&st.length>1&&null!==me?[st.reduce((e,t)=>Math.abs(Ue(t.value??0)-me)<Math.abs(Ue(e.value??0)-me)?t:e)]:st,ot=lt?xe[lt.series]?.[lt.index]?.x??n?.[lt.index]??lt.index:void 0,ct=lt?lt.x:b?Ue(rt[0]?.value??0):Xe.left+Ke(at??0),dt=lt?lt.y:b?Xe.top+Ke(at??0):Xe.top,ht=lt?(lt.x-Xe.left)/Math.max(1,Xe.width)>.6:(b?Se.fraction(rt[0]?.value??0):Ke(at??0)/Math.max(1,Ye))>.6,ut=!1===Z?{interactive:!1}:!0===Z||void 0===Z?{}:Z,mt=!0===Z||!1!==Z&&t.length>1,pt=ut.side??"bottom",ft={...Oe,hovered:oe.hovered,activeIndex:at,marks:Qe,activeMark:lt},xt=0===ve||null===ke||"value"===F&&null===ze;return l(ChartSurface,{...ee,size:le,variant:G,padded:J,className:O,legendSide:pt,legend:mt?e(ChartLegendBar,{series:t,colors:ge,options:ut,visibility:oe,size:le,swatch:R,values:ut.showValue&&null!==at?t.map((e,t)=>{const l=xe[t]?.[at]?.value;return null==l?void 0:fe(l)}):void 0}):null,table:xt?null:I?.(re)??e(ChartDataTable,{id:re,caption:Y,corner:Ne?.label,categories:be,series:t,values:xe,format:fe,locale:ae}),children:[l("div",{ref:ne,role:"img",tabIndex:xt?void 0:0,"aria-label":Y??ie.chart,"aria-describedby":xt?void 0:re,onPointerMove:e=>{"none"!==tt&&(L?ue(((e,t)=>{const l=ne.current;if(!l||0===Qe.length)return null;const a=l.getBoundingClientRect(),n=e-a.left,s=t-a.top;let i=null,r=1/0,o=1/0;return Qe.forEach((e,t)=>{const l=Math.hypot(e.x-n,e.y-s),a=void 0===e.rx?Math.max(0,l-e.r):Math.hypot(Math.max(0,Math.abs(e.x-n)-e.rx),Math.max(0,Math.abs(e.y-s)-(e.ry??e.rx)));a<=$&&(a<r||a===r&&l<o)&&(r=a,o=l,i=t)}),i})(e.clientX,e.clientY)):de(((e,t)=>{const l=ne.current;if(!l||0===ve)return null;const a=l.getBoundingClientRect(),n=b?t-a.top-Xe.top:e-a.left-Xe.left;if(n<-Ze.step||n>Ye+Ze.step)return null;const s=B?ve<=1?0:Math.round(n/Ye*(ve-1)):Math.floor(n/Ze.step);return Math.min(ve-1,Math.max(0,s))})(e.clientX,e.clientY)),"item"===tt&&pe(((e,t)=>{const l=ne.current;if(!l)return null;const a=l.getBoundingClientRect();return b?e-a.left:t-a.top})(e.clientX,e.clientY)))},onPointerLeave:clearActive,onKeyDown:"none"===tt?void 0:e=>{const t=b?"ArrowDown":"ArrowRight",l=b?"ArrowUp":"ArrowLeft";if(e.key===t)step(1);else if(e.key===l)step(-1);else if("Home"===e.key)goTo(0);else if("End"===e.key)goTo(nt-1);else{if("Escape"!==e.key)return;clearActive()}e.preventDefault()},onBlur:clearActive,className:z("relative w-full","rounded-(--plass-radius-xs)","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-2"),style:{height:we??E},children:[xt?e("div",{className:z("flex h-full items-center justify-center text-(--plass-muted-fg)",j[le]),children:U??ie.empty}):se>0?l("svg",{width:se,height:He||"100%",viewBox:`0 0 ${se} ${He}`,"aria-hidden":"true",className:"block overflow-visible",children:[e(ChartAxes,{plot:Xe,scale:Se,band:Ze,horizontal:b,inset:B,categoryPx:Ke,valuePx:Ue,tickTexts:Ae,categoryTexts:Fe,categoryScale:Pe,categoryValuePx:Ge,valueAxis:Ce,categoryAxis:Ne,fontSize:Me,zeroPx:Je}),null===at||L||"index"!==tt||!1===et.crosshair?null:(()=>{const t=Ke(at);return e("line",b?{x1:Xe.left,x2:Xe.left+Xe.width,y1:Xe.top+t,y2:Xe.top+t,stroke:"var(--plass-chart-baseline)",strokeWidth:1}:{x1:Xe.left+t,x2:Xe.left+t,y1:Xe.top,y2:Xe.top+Xe.height,stroke:"var(--plass-chart-baseline)",strokeWidth:1})})(),Q(ft)]}):null,null!==at&&rt.length>0&&"none"!==tt?et.render?e("div",{className:"pointer-events-none absolute z-10",style:ht?{right:`calc(100% - ${ct}px + 10px)`,top:dt}:{left:ct+10,top:dt},children:et.render({index:at,category:ot??be[at],items:rt})}):e(ChartTooltipPanel,{heading:it?it.heading:m(ot??be[at],ae),items:rt,x:ct,y:dt,flip:ht,size:le}):null]}),"none"===tt?null:e(ChartStatus,{heading:null===at?void 0:it?.heading??m(ot??be[at],ae),items:rt})]})}function ChartAxes({plot:a,scale:n,horizontal:s,categoryPx:i,valuePx:r,tickTexts:o,categoryTexts:c,categoryScale:d,categoryValuePx:h,valueAxis:m,categoryAxis:p,fontSize:f,zeroPx:x}){const y=!1!==m?.grid&&!m?.hidden,k=!p?.hidden&&(p?.grid??null!==d),categoryAlong=e=>d?h(d.ticks[e]):(s?a.top:a.left)+i(e),w=b(c.length,s?a.height:a.width,s?1.8*f:Math.max(...c.map(e=>v(e,f)),1)+12),M=b(n.ticks.length,s?a.width:a.height,s?Math.max(...o.map(e=>v(e,f)),1)+16:2*f),C=c.length>1?Math.abs(categoryAlong(1)-categoryAlong(0)):a.width,N=n.ticks.length>1?Math.abs(r(n.ticks[1])-r(n.ticks[0])):a.height,S=u(c.length,w,C,s?1.8*f:v(c[c.length-1]??"",f)),z=u(n.ticks.length,M,N,s?v(o[o.length-1]??"",f):1.6*f);return l("g",{children:[n.ticks.map((t,i)=>{const c=r(t),d=Math.abs(t)<1e-9;return l("g",{children:[y?e("line",s?{x1:c,x2:c,y1:a.top,y2:a.top+a.height,stroke:d?"var(--plass-chart-baseline)":"var(--plass-chart-grid)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:c,y2:c,stroke:d?"var(--plass-chart-baseline)":"var(--plass-chart-grid)",strokeWidth:1}):null,m?.hidden||!g(i,n.ticks.length,M,z)?null:e("text",s?{x:c,y:a.top+a.height+f+6,textAnchor:0===i?"start":i===n.ticks.length-1?"end":"middle",fontSize:f,fill:"var(--plass-muted-fg)",className:"tabular-nums",children:o[i]}:{x:a.left-8,y:c,textAnchor:"end",dominantBaseline:"central",fontSize:f,fill:"var(--plass-muted-fg)",className:"tabular-nums",children:o[i]})]},t)}),p?.hidden?null:l(t,{children:[e("line",s?{x1:x,x2:x,y1:a.top,y2:a.top+a.height,stroke:"var(--plass-chart-axis)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:x,y2:x,stroke:"var(--plass-chart-axis)",strokeWidth:1}),c.map((t,n)=>{const i=categoryAlong(n),r=g(n,c.length,w,S);return s?r?e("text",{x:a.left-8,y:i,textAnchor:"end",dominantBaseline:"central",fontSize:f,fill:"var(--plass-muted-fg)",className:d?"tabular-nums":void 0,children:t},n):null:l("g",{children:[k?e("line",{x1:i,x2:i,y1:a.top,y2:a.top+a.height,stroke:"var(--plass-chart-grid)",strokeWidth:1}):null,r?e("text",{x:i,y:a.top+a.height+f+6,textAnchor:d?0===n?"start":n===c.length-1?"end":"middle":"middle",fontSize:f,fill:"var(--plass-muted-fg)",className:d?"tabular-nums":void 0,children:t}):null]},n)})]}),m?.label?e("text",{x:s?a.left+a.width:a.left,y:s?a.top+a.height+2*f+12:a.top-8,textAnchor:s?"end":"start",fontSize:f,fill:"var(--plass-muted-fg)",fontWeight:500,children:m.label}):null,p?.label&&!s?e("text",{x:a.left+a.width,y:a.top+a.height+2*f+12,textAnchor:"end",fontSize:f,fill:"var(--plass-muted-fg)",fontWeight:500,children:p.label}):null]})}export{ChartDataTable,ChartLegendBar,ChartScaleLegend,ChartStatus,ChartSurface,ChartTooltipPanel,useMeasuredWidth,useVisibility};
1
+ "use client";import{jsx as e,Fragment as t,jsxs as l}from"react/jsx-runtime";import*as a from"react";import{PlBox as n}from"../components/box/PlBox.js";import{bandScale as s,categoryAt as i,categoryCount as r,categoriesAreDates as o,categoryExtent as c,chartFontSizes as d,compactNumber as u,extentOf as h,fitCategoryLabels as m,fitsLast as p,formatCategory as f,formatTimeTicks as x,markerRadii as g,plotHeights as v,seriesColor as b,showsTick as y,textWidth as k,tickStride as w,toValues as M,timeScale as C,valueScale as N,writeChartValue as S}from"./chart.js";import{useDefaults as z}from"./defaults.js";import{usePlElementSize as P}from"../hooks/usePlElementSize.js";import{useLabels as A}from"./labels.js";import{cx as j,glassClasses as B,hasContent as W,metaTextClasses as _,srOnlyClasses as T,transitionClasses as $}from"./styles.js";const I=[];function useMeasuredWidth(e){return P(e)?.width??0}export const markTransitionClasses=["[transition:opacity_var(--plass-duration)_var(--plass-ease),","r_var(--plass-duration)_var(--plass-ease),","scale_var(--plass-duration)_var(--plass-ease)]"].join("");function useVisibility(e){const[t,l]=a.useState(()=>{const t=new Set;return e.forEach((e,l)=>{e.hidden&&t.add(l)}),t}),[n,s]=a.useState(null),i=a.useCallback(e=>{l(t=>{const l=new Set(t);return l.has(e)?l.delete(e):l.add(e),l})},[]);return{visible:e.map((e,l)=>!t.has(l)),hovered:n,toggle:i,setHovered:s}}const L={top:"flex-col-reverse",bottom:"flex-col",left:"flex-row-reverse rtl:flex-row",right:"flex-row rtl:flex-row-reverse"},F={start:"justify-start",center:"justify-center",end:"justify-end"};function ChartLegendBar({series:a,colors:n,options:s,visibility:i,size:r,values:o,swatch:c}){const d=!1!==s.interactive,u="left"===s.side||"right"===s.side;return e("ul",{className:j("m-0 flex list-none flex-wrap items-center gap-x-3 gap-y-1 p-0",u?"min-w-0 flex-col items-start":"",F[s.align??"center"],_[r]),children:a.map((a,s)=>{const r=i.visible[s],u=null!==i.hovered&&i.hovered!==s,h=a.name??`${s+1}`,m=r?n[s]:`color-mix(in oklab, ${n[s]} 40%, transparent)`,p=l(t,{children:[e("span",c?{"aria-hidden":"true",className:"flex size-2.5 shrink-0 items-center justify-center",children:c(s,m)}:{"aria-hidden":"true",className:`size-2.5 shrink-0 rounded-[0.1875rem] ${$}`,style:{backgroundColor:m}}),e("span",{className:"min-w-0 truncate",children:h}),o?.[s]?e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:o[s]}):null]});return e("li",{className:"min-w-0",children:d?e("button",{type:"button","aria-pressed":r,onClick:()=>i.toggle(s),onPointerEnter:()=>i.setHovered(s),onPointerLeave:()=>i.setHovered(null),onFocus:()=>i.setHovered(s),onBlur:()=>i.setHovered(null),className:j("flex min-w-0 cursor-pointer items-center gap-1.5 rounded-(--plass-radius-xs)","px-1 py-0.5 text-(--plass-fg)","[transition-property:background-color,color,opacity]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]","hover:bg-(--p-soft)","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-1",r?"":"text-(--plass-muted-fg) line-through",u?"opacity-55":""),children:p}):e("span",{className:j("flex min-w-0 items-center gap-1.5 px-1 py-0.5 text-(--plass-fg)",r?"":"text-(--plass-muted-fg) line-through"),children:p})},a.name??s)})})}function ChartScaleLegend({steps:a,from:n,to:s,middle:i,align:r,vertical:o,size:c}){return e("div",{className:j("flex",o?"":F[r]),children:l("div",{className:j("grid grid-cols-[auto_auto_auto] items-center gap-x-2",_[c]),children:[e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:n}),e("span",{"aria-hidden":"true",className:j("flex h-2.5 overflow-hidden rounded-[0.1875rem]",o?"w-20":"w-24"),children:a.map(t=>e("span",{className:"h-full flex-1",style:{backgroundColor:t}},t))}),e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:s}),i?l(t,{children:[e("span",{}),e("span",{className:"text-center tabular-nums text-(--plass-muted-fg)",children:i}),e("span",{})]}):null]})})}function ChartTooltipPanel({heading:t,items:a,x:n,y:s,flip:i,size:r}){return l("div",{"data-plass-tooltip":"",className:j("pointer-events-none absolute z-10 max-w-56 min-w-24","rounded-(--plass-radius-sm) border p-2",B,"bg-(--plass-glass-press) [border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]",_[r]),style:i?{right:`calc(100% - ${n}px + 10px)`,top:s}:{left:n+10,top:s},children:[e("div",{className:"mb-1 font-medium text-(--plass-fg)",children:t}),e("ul",{className:"m-0 flex list-none flex-col gap-0.5 p-0",children:a.map(t=>l("li",{className:"flex items-center gap-1.5",children:[e("span",{"aria-hidden":"true",className:"size-2 shrink-0 rounded-[0.125rem]",style:{backgroundColor:t.color}}),t.name?e("span",{className:"min-w-0 flex-1 truncate text-(--plass-muted-fg)",children:t.name}):null,e("span",{className:"ms-auto shrink-0 font-medium tabular-nums text-(--plass-fg)",children:t.label??t.formatted})]},t.seriesIndex))})]})}function ChartStatus({heading:n,items:s}){return e("span",{role:"status","aria-live":"polite",className:T,children:0===s.length?null:l(t,{children:[W(n)?l(t,{children:[n,", "]}):null,s.map((e,t)=>l(a.Fragment,{children:[t>0?", ":null,e.name?`${e.name}: `:null,e.label??e.formatted]},e.seriesIndex))]})})}const R=/* @__PURE__ */a.memo(function ChartDataTable({id:t,caption:a,corner:n,categories:s,series:i,values:r,format:o,locale:c}){return l("table",{id:t,className:T,children:[a?e("caption",{children:a}):null,e("thead",{children:l("tr",{children:[e("th",{scope:"col",children:n??""}),i.map((t,l)=>e("th",{scope:"col",children:t.name??l+1},t.name??l))]})}),e("tbody",{children:s.map((t,a)=>l("tr",{children:[e("th",{scope:"row",children:f(t,c)}),i.map((t,l)=>{const n=r[l]?.[a];return e("td",void 0!==n?.label?{children:n.label}:{children:null==n?.value?"":o(n.value)},t.name??l)})]},a))})]})});function ChartSurface({legend:t,legendSide:a,children:s,table:i,className:r,...o}){return l(n,{...o,className:j("relative flex gap-3",L[a],r??void 0),children:[e("div",{className:"relative min-w-0 flex-1",children:s}),t,i]})}export function CartesianChart({series:n,categories:p,xAxis:y,yAxis:w,horizontal:P=!1,stacked:B=!1,includeZero:W=!0,bandRatio:$=1,inset:L=!1,headroom:F=0,markInset:V=0,xScale:E="band",marks:H,markRadius:D=24,table:X,swatch:Y,scale:Z,markTooltip:K,height:U,format:q,locale:G,label:J,legend:O,tooltip:Q,empty:ee,size:te,variant:le="ghost",padded:ae=!1,className:ne,children:se,...ie}){const re=z(),oe=te??re.size??"md",ce=G??re.locale,de=a.useRef(null),ue=useMeasuredWidth(de),he=A(),me=a.useId(),pe=a.useId(),fe=useVisibility(n),[xe,ge]=a.useState(null),[ve,be]=a.useState(null),[ye,ke]=a.useState(null),we=a.useCallback(e=>S(e,q,ce),[q,ce]),Me=a.useMemo(()=>M(n),[n]),Ce=a.useMemo(()=>n.map((e,t)=>b(e,t)),[n]),Ne=a.useMemo(()=>n.map(e=>!0===e.dashed),[n]),Se=r(n),ze=a.useMemo(()=>Array.from({length:Se},(e,t)=>i(t,p,Me)),[Se,p,Me]),Pe=Me.filter((e,t)=>fe.visible[t]),Ae=h(Pe,B),je=a.useMemo(()=>n.flatMap((e,t)=>{if(!fe.visible[t])return[];const l=[...Me[t]??[]].reverse().find(e=>null!==e.value),a=e.name??`${t+1}`;return void 0===l?[{name:a,said:null}]:[{name:a,said:l.label??we(l.value)}]}),[n,Me,fe.visible,we]),Be="number"==typeof U?U:void 0===U?v[oe]:null,We=d[oe],_e=w,Te=y,$e=Z??N(Ae,{min:_e?.min,max:_e?.max,tickCount:_e?.tickCount,includeZero:W}),Ie="value"===E?c(Pe,p):null,Le="value"===E&&o(Me,p),Fe="value"!==E?null:Le?C(Ie,{min:Te?.min,max:Te?.max,tickCount:Te?.tickCount}):N(Ie,{min:Te?.min,max:Te?.max,tickCount:Te?.tickCount,includeZero:!1}),Re=Fe&&"unit"in Fe?x(Fe.ticks,Fe.unit,ce):null,Ve=$e.ticks.map((e,t)=>_e?.tickFormat?String(_e.tickFormat(e,t)):we(e)),Ee=Te?.tickFormat,He=a.useMemo(()=>ze.map((e,t)=>Ee?String(Ee(e,t)):f(e,ce)),[ze,Ee,ce]),De=Fe?Fe.ticks.map((e,t)=>Ee?String(Ee(Le?new Date(e):e,t)):Re?.[t]??u(e,ce)):He,Xe=Ve.reduce((e,t)=>Math.max(e,k(t,We)),0),Ye=We+6,Ze=_e?.hidden?0:Xe+10+(_e?.label?Ye:0),Ke=(ue-(P?0:Ze)-16)/Math.max(1,Se),Ue=null!==Fe,qe=a.useMemo(()=>m(De,{horizontal:P,slot:Ke,fontSize:We,ticks:Ue}),[De,P,Ke,We,Ue]),Ge=a.useMemo(()=>qe.reduce((e,t)=>Math.max(e,k(t,We)),0),[qe,We]),Je=P?Te?.hidden?0:Ge+10+(Te?.label?Ye:0):Ze,Oe=P?_e?.hidden?0:We+12+(_e?.label?Ye:0):Te?.hidden?0:We+12+(Te?.label?Ye:0),Qe=(P?Te:_e)?.thickness??Je,et=(P?_e:Te)?.thickness??Oe,tt=(P||Fe?12:Math.max(8,qe.length?Ge/2:8))+V,lt=g[oe]+4+F+V,at=Be??0,nt={left:Qe+V,top:lt,width:Math.max(0,ue-Qe-V-tt),height:Math.max(0,at-lt-et-V)},st=P?nt.height:nt.width,it=s(L?Math.max(1,Se-1):Se,st,$),rt=a.useCallback(e=>L?Se<=1?st/2:st*e/(Se-1):it.centre(e),[L,Se,st,it]),ot=a.useCallback(e=>P?nt.left+$e.fraction(e)*nt.width:nt.top+(1-$e.fraction(e))*nt.height,[P,nt.left,nt.top,nt.width,nt.height,$e]),ct=a.useCallback((e,t)=>P?{x:ot(t),y:nt.top+rt(e)}:{x:nt.left+rt(e),y:ot(t)},[P,ot,rt,nt.left,nt.top]),dt=a.useCallback(e=>P?nt.top+(1-(Fe?.fraction(e)??0))*nt.height:nt.left+(Fe?.fraction(e)??0)*nt.width,[P,nt.left,nt.top,nt.width,nt.height,Fe]),ut=ot(Math.min(Math.max(0,$e.min),$e.max)),ht={plot:nt,values:Me,visible:fe.visible,colors:Ce,dashed:Ne,scale:$e,band:it,horizontal:P,valuePx:ot,categoryPx:rt,point:ct,categoryScale:Fe,categoryValuePx:dt,zeroPx:ut,categories:ze,format:we,size:oe},mt=H?H(ht):I,pt=!1===Q?{mode:"none"}:!0===Q||void 0===Q?{}:Q,ft=pt.mode??(H?"item":"index"),xt=null===ve?null:mt[ve]??null,gt=H?xt?xt.index:null:xe,vt=H?mt.length:Se,clearActive=()=>{ge(null),be(null),ke(null)},goTo=e=>{const t=null===e?null:Math.min(vt-1,Math.max(0,e));H?be(t):ge(t)},step=e=>{ke(null),goTo(((H?ve:xe)??(e>0?-1:vt))+e)},bt=null===gt?[]:n.flatMap((e,t)=>{if(!fe.visible[t]||xt&&xt.series!==t)return[];const l=Me[t]?.[gt];return l&&null!==l.value?[{seriesIndex:t,name:e.name,color:l.color??Ce[t],value:l.value,formatted:we(l.value),label:l.label}]:[]}),yt=xt&&K?K(xt):null,kt=yt?yt.items:"item"===ft&&bt.length>1&&null!==ye?[bt.reduce((e,t)=>Math.abs(ot(t.value??0)-ye)<Math.abs(ot(e.value??0)-ye)?t:e)]:bt,wt=xt?Me[xt.series]?.[xt.index]?.x??p?.[xt.index]??xt.index:void 0,Mt=xt?xt.x:P?ot(kt[0]?.value??0):nt.left+rt(gt??0),Ct=xt?xt.y:P?nt.top+rt(gt??0):nt.top,Nt=xt?(xt.x-nt.left)/Math.max(1,nt.width)>.6:(P?$e.fraction(kt[0]?.value??0):rt(gt??0)/Math.max(1,st))>.6,St=!1===O?{interactive:!1}:!0===O||void 0===O?{}:O,zt=!0===O||!1!==O&&n.length>1,Pt=St.side??"bottom",At={...ht,hovered:fe.hovered,activeIndex:gt,marks:mt,activeMark:xt},jt=0===Se||null===Ae||"value"===E&&null===Ie;return l(ChartSurface,{...ie,size:oe,variant:le,padded:ae,className:ne,legendSide:Pt,legend:zt?e(ChartLegendBar,{series:n,colors:Ce,options:St,visibility:fe,size:oe,swatch:Y,values:St.showValue&&null!==gt?n.map((e,t)=>{const l=Me[t]?.[gt]?.value;return null==l?void 0:we(l)}):void 0}):null,table:jt?null:X?.(me)??e(R,{id:me,caption:J,corner:Te?.label,categories:ze,series:n,values:Me,format:we,locale:ce}),children:[l("div",{ref:de,role:"img",tabIndex:jt?void 0:0,"aria-label":J??he.chart,"aria-describedby":jt?void 0:pe,onPointerMove:e=>{"none"!==ft&&(H?be(((e,t)=>{const l=de.current;if(!l||0===mt.length)return null;const a=l.getBoundingClientRect(),n=e-a.left,s=t-a.top;let i=null,r=1/0,o=1/0;return mt.forEach((e,t)=>{const l=Math.hypot(e.x-n,e.y-s),a=void 0===e.rx?Math.max(0,l-e.r):Math.hypot(Math.max(0,Math.abs(e.x-n)-e.rx),Math.max(0,Math.abs(e.y-s)-(e.ry??e.rx)));a<=D&&(a<r||a===r&&l<o)&&(r=a,o=l,i=t)}),i})(e.clientX,e.clientY)):ge(((e,t)=>{const l=de.current;if(!l||0===Se)return null;const a=l.getBoundingClientRect(),n=P?t-a.top-nt.top:e-a.left-nt.left;if(n<-it.step||n>st+it.step)return null;const s=L?Se<=1?0:Math.round(n/st*(Se-1)):Math.floor(n/it.step);return Math.min(Se-1,Math.max(0,s))})(e.clientX,e.clientY)),"item"!==ft||H||ke(((e,t)=>{const l=de.current;if(!l)return null;const a=l.getBoundingClientRect();return P?e-a.left:t-a.top})(e.clientX,e.clientY)))},onPointerLeave:clearActive,onKeyDown:"none"===ft?void 0:e=>{const t=P?"ArrowDown":"ArrowRight",l=P?"ArrowUp":"ArrowLeft";if(e.key===t)step(1);else if(e.key===l)step(-1);else if("Home"===e.key)goTo(0);else if("End"===e.key)goTo(vt-1);else{if("Escape"!==e.key)return;clearActive()}e.preventDefault()},onBlur:clearActive,className:j("relative w-full","rounded-(--plass-radius-xs)","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-2"),style:{height:Be??U},children:[jt?e("div",{className:j("flex h-full items-center justify-center text-(--plass-muted-fg)",_[oe]),children:ee??he.empty}):ue>0?l("svg",{width:ue,height:at||"100%",viewBox:`0 0 ${ue} ${at}`,"aria-hidden":"true",className:"block overflow-visible",children:[e(ChartAxes,{plot:nt,scale:$e,band:it,horizontal:P,inset:L,categoryPx:rt,valuePx:ot,tickTexts:Ve,categoryTexts:qe,categoryScale:Fe,categoryValuePx:dt,valueAxis:_e,categoryAxis:Te,fontSize:We,zeroPx:ut}),null===gt||H||"index"!==ft||!1===pt.crosshair?null:(()=>{const t=rt(gt);return e("line",P?{x1:nt.left,x2:nt.left+nt.width,y1:nt.top+t,y2:nt.top+t,stroke:"var(--plass-chart-baseline)",strokeWidth:1}:{x1:nt.left+t,x2:nt.left+t,y1:nt.top,y2:nt.top+nt.height,stroke:"var(--plass-chart-baseline)",strokeWidth:1})})(),se(At)]}):null,null!==gt&&kt.length>0&&"none"!==ft?pt.render?e("div",{className:"pointer-events-none absolute z-10",style:Nt?{right:`calc(100% - ${Mt}px + 10px)`,top:Ct}:{left:Mt+10,top:Ct},children:pt.render({index:gt,category:wt??ze[gt],items:kt})}):e(ChartTooltipPanel,{heading:yt?yt.heading:f(wt??ze[gt],ce),items:kt,x:Mt,y:Ct,flip:Nt,size:oe}):null]}),jt?null:e("span",{id:pe,className:T,children:je.map((e,n)=>l(a.Fragment,{children:[n>0?", ":null,null===e.said?e.name:l(t,{children:[e.name," ",e.said]})]},n))}),"none"===ft?null:e(ChartStatus,{heading:null===gt?void 0:yt?.heading??f(wt??ze[gt],ce),items:kt})]})}function ChartAxes({plot:a,scale:n,horizontal:s,categoryPx:i,valuePx:r,tickTexts:o,categoryTexts:c,categoryScale:d,categoryValuePx:u,valueAxis:h,categoryAxis:m,fontSize:f,zeroPx:x}){const g=!1!==h?.grid&&!h?.hidden,v=!m?.hidden&&(m?.grid??null!==d),categoryAlong=e=>d?u(d.ticks[e]):(s?a.top:a.left)+i(e),b=w(c.length,s?a.height:a.width,s?1.8*f:Math.max(...c.map(e=>k(e,f)),1)+12),M=w(n.ticks.length,s?a.width:a.height,s?Math.max(...o.map(e=>k(e,f)),1)+16:2*f),C=c.length>1?Math.abs(categoryAlong(1)-categoryAlong(0)):a.width,N=n.ticks.length>1?Math.abs(r(n.ticks[1])-r(n.ticks[0])):a.height,S=p(c.length,b,C,s?1.8*f:k(c[c.length-1]??"",f)),z=p(n.ticks.length,M,N,s?k(o[o.length-1]??"",f):1.6*f);return l("g",{children:[n.ticks.map((t,i)=>{const c=r(t),d=Math.abs(t)<1e-9;return l("g",{children:[g?e("line",s?{x1:c,x2:c,y1:a.top,y2:a.top+a.height,stroke:d?"var(--plass-chart-baseline)":"var(--plass-chart-grid)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:c,y2:c,stroke:d?"var(--plass-chart-baseline)":"var(--plass-chart-grid)",strokeWidth:1}):null,h?.hidden||!y(i,n.ticks.length,M,z)?null:e("text",s?{x:c,y:a.top+a.height+f+6,textAnchor:0===i?"start":i===n.ticks.length-1?"end":"middle",fontSize:f,fill:"var(--plass-muted-fg)",className:"tabular-nums",children:o[i]}:{x:a.left-8,y:c,textAnchor:"end",dominantBaseline:"central",fontSize:f,fill:"var(--plass-muted-fg)",className:"tabular-nums",children:o[i]})]},t)}),m?.hidden?null:l(t,{children:[e("line",s?{x1:x,x2:x,y1:a.top,y2:a.top+a.height,stroke:"var(--plass-chart-axis)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:x,y2:x,stroke:"var(--plass-chart-axis)",strokeWidth:1}),c.map((t,n)=>{const i=categoryAlong(n),r=y(n,c.length,b,S);return r||!s&&v?s?e("text",{x:a.left-8,y:i,textAnchor:"end",dominantBaseline:"central",fontSize:f,fill:"var(--plass-muted-fg)",className:d?"tabular-nums":void 0,children:t},n):l("g",{children:[v?e("line",{x1:i,x2:i,y1:a.top,y2:a.top+a.height,stroke:"var(--plass-chart-grid)",strokeWidth:1}):null,r?e("text",{x:i,y:a.top+a.height+f+6,textAnchor:d?0===n?"start":n===c.length-1?"end":"middle":"middle",fontSize:f,fill:"var(--plass-muted-fg)",className:d?"tabular-nums":void 0,children:t}):null]},n):null})]}),h?.label?e("text",{x:s?a.left+a.width:a.left,y:s?a.top+a.height+2*f+12:a.top-8,textAnchor:s?"end":"start",fontSize:f,fill:"var(--plass-muted-fg)",fontWeight:500,children:h.label}):null,m?.label&&!s?e("text",{x:a.left+a.width,y:a.top+a.height+2*f+12,textAnchor:"end",fontSize:f,fill:"var(--plass-muted-fg)",fontWeight:500,children:m.label}):null]})}export{R as ChartDataTable,ChartLegendBar,ChartScaleLegend,ChartStatus,ChartSurface,ChartTooltipPanel,useMeasuredWidth,useVisibility};
@@ -1 +1 @@
1
- import{jsx as l,jsxs as e}from"react/jsx-runtime";import{areaPath as t,chartFontSizes as r,linePath as n,lineWidths as o,markerRadii as a,markGap as s}from"./chart.js";import{markTransitionClasses as i}from"./chart-frame.js";export function LineSeries({context:u,curve:f,filled:c,stacked:p,markers:d,valueLabels:m,connectNulls:x,gradient:h,idPrefix:v}){const{values:k,visible:$,colors:b,hovered:y,activeIndex:g,plot:j,point:C,zeroPx:L,size:N,format:W}=u,z=o[N],B=a[N],P=$.indexOf(!0),E=[],G=[];return k.forEach((l,e)=>{const t=l.map((l,e)=>G[e]??0);E.push(t),p&&$[e]&&l.forEach((l,e)=>{G[e]=(G[e]??0)+(l.value??0)})}),e("g",{children:[e("defs",{children:[h?b.map((t,r)=>e("linearGradient",{id:`${v}-stroke-${r}`,x1:"0",y1:"0",x2:"1",y2:"0",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${t} 45%, transparent)`}),l("stop",{offset:"100%",stopColor:t})]},`stroke-${r}`)):null,c&&!p?b.map((t,r)=>e("linearGradient",{id:`${v}-fill-${r}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${t} 28%, transparent)`}),l("stop",{offset:"100%",stopColor:`color-mix(in oklab, ${t} 2%, transparent)`})]},`fill-${r}`)):null]}),k.map((o,a)=>{if(!$[a])return null;const u=b[a],k=null!==y&&y!==a&&$[y],G=o.map((l,e)=>{if(null===l.value)return null;const t=p?E[a][e]+l.value:l.value;return C(e,t)}),M=x?G.filter(Boolean):G,S=o.map((l,e)=>null===l.value?null:p?C(e,E[a][e]):{x:C(e,l.value).x,y:L}),w=c&&p,A=function labelledPoints(l,e){if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let t=l.length-1;t>=0;t--)if(null!==l[t].value){e=t;break}return l=>l===e}let t=1/0,r=-1/0;for(const e of l)null!==e.value&&(t=Math.min(t,e.value),r=Math.max(r,e.value));return e=>{const n=l[e].value;return null!==n&&(n===t||n===r)}}(o,m);return e("g",{opacity:k?.28:1,className:i,children:[c?l("path",{d:t(M,x?S.filter(Boolean):S,f),fill:p?`color-mix(in oklab, ${u} 70%, transparent)`:`url(#${v}-fill-${a})`,stroke:"none"}):null,w&&a!==P?l("path",{d:n(x?S.filter(Boolean):S,f),fill:"none",stroke:"var(--plass-chart-gap)",strokeWidth:s}):null,w?null:l("path",{d:n(M,f),fill:"none",stroke:h?`url(#${v}-stroke-${a})`:u,strokeWidth:z,strokeLinecap:"round",strokeLinejoin:"round"}),G.map((e,t)=>e&&("all"===d||"auto"===d&&o.length<=14||t===g)?l("circle",{cx:e.x,cy:e.y,r:t===g?B+1:B,fill:o[t].color??u,stroke:"var(--plass-chart-gap)",strokeWidth:s,className:i},t):null),"none"===m?null:G.map((e,t)=>{const n=o[t].value;return e&&null!==n&&A(t)?l("text",{x:e.x,y:e.y-B-5,textAnchor:e.x>j.left+j.width-24?"end":e.x<j.left+24?"start":"middle",fontSize:r[N],fontWeight:500,fill:"var(--plass-fg)",className:"tabular-nums",children:o[t].label??W(n)},`label-${t}`):null})]},a)})]})}
1
+ import{jsx as l,jsxs as e}from"react/jsx-runtime";import{areaPath as r,chartFontSizes as t,dimmedByHover as o,labelledPoints as a,linePath as n,lineDash as s,lineWidths as i,markerRadii as c,markGap as u}from"./chart.js";import{markTransitionClasses as f}from"./chart-frame.js";export function LineSeries({context:p,curve:d,filled:m,stacked:x,markers:h,valueLabels:k,connectNulls:v,gradient:$,idPrefix:y}){const{values:b,visible:g,colors:j,dashed:C,hovered:L,activeIndex:N,plot:W,point:z,zeroPx:B,size:E,format:G}=p,P=i[E],S=c[E],w=g.indexOf(!0),A=[],D=[];return b.forEach((l,e)=>{const r=l.map((l,e)=>D[e]??0);A.push(r),x&&g[e]&&l.forEach((l,e)=>{D[e]=(D[e]??0)+(l.value??0)})}),e("g",{children:[e("defs",{children:[$?j.map((r,t)=>e("linearGradient",{id:`${y}-stroke-${t}`,x1:"0",y1:"0",x2:"1",y2:"0",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 45%, transparent)`}),l("stop",{offset:"100%",stopColor:r})]},`stroke-${t}`)):null,m&&!x?j.map((r,t)=>e("linearGradient",{id:`${y}-fill-${t}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 28%, transparent)`}),l("stop",{offset:"100%",stopColor:`color-mix(in oklab, ${r} 2%, transparent)`})]},`fill-${t}`)):null]}),b.map((i,c)=>{if(!g[c])return null;const p=j[c],b=o(L,c,g),D=i.map((l,e)=>{if(null===l.value)return null;const r=x?A[c][e]+l.value:l.value;return z(e,r)}),I=v?D.filter(Boolean):D,O=i.map((l,e)=>null===l.value?null:x?z(e,A[c][e]):{x:z(e,l.value).x,y:B}),q=m&&x,F=a(i,k);return e("g",{opacity:b?.28:1,className:f,children:[m?l("path",{d:r(I,v?O.filter(Boolean):O,d),fill:x?`color-mix(in oklab, ${p} 70%, transparent)`:`url(#${y}-fill-${c})`,stroke:"none"}):null,q&&c!==w?l("path",{d:n(v?O.filter(Boolean):O,d),fill:"none",stroke:"var(--plass-chart-gap)",strokeWidth:u}):null,q?null:l("path",{d:n(I,d),fill:"none",stroke:$?`url(#${y}-stroke-${c})`:p,strokeWidth:P,strokeDasharray:C[c]?s:void 0,strokeLinecap:"round",strokeLinejoin:"round"}),D.map((e,r)=>e&&("all"===h||"auto"===h&&i.length<=14||r===N)?l("circle",{cx:e.x,cy:e.y,r:r===N?S+1:S,fill:i[r].color??p,stroke:"var(--plass-chart-gap)",strokeWidth:u,className:f},r):null),"none"===k?null:D.map((e,r)=>{const o=i[r].value;return e&&null!==o&&F(r)?l("text",{x:e.x,y:e.y-S-5,textAnchor:e.x>W.left+W.width-24?"end":e.x<W.left+24?"start":"middle",fontSize:t[E],fontWeight:500,fill:"var(--plass-fg)",className:"tabular-nums",children:i[r].label??G(o)},`label-${r}`):null})]},c)})]})}
@@ -16,7 +16,7 @@
16
16
  * makes.
17
17
  */
18
18
  import type * as React from 'react';
19
- import type { PlassChartCategory, PlassChartDatum, PlassChartSeries, PlassDensity, PlassSize } from '../types.js';
19
+ import type { PlassChartCategory, PlassChartDatum, PlassChartSeries, PlassChartValueLabels, PlassDensity, PlassSize } from '../types.js';
20
20
  /**
21
21
  * How tall a plot is when nobody said, in pixels.
22
22
  *
@@ -42,6 +42,15 @@ export declare const sparklineHeights: Record<PlassSize, number>;
42
42
  * enough to hold a hue at 3:1.
43
43
  */
44
44
  export declare const lineWidths: Record<PlassSize, number>;
45
+ /**
46
+ * The `stroke-dasharray` of a `dashed` series: a 6px dash and a 4px gap.
47
+ *
48
+ * Fixed rather than scaled by the line's weight, and the same two numbers the
49
+ * Flutter build cuts its path into: a dash pattern is read as a *rhythm*, and
50
+ * one that stretched with the size ladder would change what the line means
51
+ * between an `sm` chart and an `lg` one.
52
+ */
53
+ export declare const lineDash = "6 4";
45
54
  /**
46
55
  * The radius of a marker. `md` is 4, so the dot is 8px across before its ring —
47
56
  * the floor below which a marker stops being something a pointer can find.
@@ -92,6 +101,16 @@ export declare function resolveColor(value: string): string;
92
101
  * "Other" series, or draw a second chart.
93
102
  */
94
103
  export declare function seriesColor(series: Pick<PlassChartSeries, 'color'> | undefined, index: number, palette?: readonly string[]): string;
104
+ /**
105
+ * Whether the mark of `index` fades while the legend entry of `hovered` is
106
+ * under the pointer.
107
+ *
108
+ * A hovered entry dims the *others* — but only when the series it names is
109
+ * actually on the plot. Pointing at an entry that is switched off would
110
+ * otherwise fade every visible series to make room for one that is not there,
111
+ * which reads as the whole chart going grey for no reason.
112
+ */
113
+ export declare function dimmedByHover(hovered: number | null, index: number, visible: readonly boolean[]): boolean;
95
114
  /** A datum unpacked into the shape the drawing code reads. */
96
115
  export interface ChartValue {
97
116
  value: number | null;
@@ -111,6 +130,32 @@ export interface ChartValue {
111
130
  export declare function toValue(datum: PlassChartDatum): ChartValue;
112
131
  /** Every series unpacked, in the order it was given. */
113
132
  export declare function toValues(series: readonly PlassChartSeries[]): ChartValue[][];
133
+ /**
134
+ * Which points of a series get a value label, decided once for the whole
135
+ * series.
136
+ *
137
+ * Once and not per point, which is the only thing worth saying about it: asking
138
+ * "is this the series' high" inside the loop over the points means walking the
139
+ * series again for each of them, and a five-hundred-point line then does a
140
+ * quarter of a million comparisons to place two labels — on every render, which
141
+ * on a chart being hovered is every frame. `last` is the last point that is
142
+ * there rather than the last slot, so a series that ends in a gap still says
143
+ * where it got to.
144
+ */
145
+ export declare function labelledPoints(one: readonly {
146
+ value: number | null;
147
+ }[], valueLabels: PlassChartValueLabels): (index: number) => boolean;
148
+ /**
149
+ * Every category of a stacked chart renormalised to a hundred.
150
+ *
151
+ * A change to the data rather than to the drawing, which is what lets the axis,
152
+ * the tooltip and the table agree that the number drawn is a share. The number
153
+ * the caller passed survives as each point's `label`, written by `write` the way
154
+ * the chart writes every other value — a chart stacked to `full` that can only
155
+ * tell a reader percentages has thrown away what it was given, and one that
156
+ * writes a revenue as `4830` beside a `$` axis has thrown away how it was given.
157
+ */
158
+ export declare function stackToFull(series: readonly PlassChartSeries[], write: (value: number) => string): PlassChartSeries[];
114
159
  /**
115
160
  * A category as a number, for a category axis that is really a value axis.
116
161
  *
@@ -129,6 +174,13 @@ export declare function toNumber(value: PlassChartCategory | undefined): number
129
174
  * x at every index and there is no column for them to share.
130
175
  */
131
176
  export declare function pointX(value: ChartValue, index: number, categories: readonly PlassChartCategory[] | undefined): number | null;
177
+ /**
178
+ * Whether the positions along a chart's x axis are moments.
179
+ *
180
+ * Such an axis runs on milliseconds, and ticking milliseconds by 1-2-5 puts a
181
+ * `1.7T` under every mark. A dated axis ticks where a calendar does instead.
182
+ */
183
+ export declare function categoriesAreDates(values: readonly ChartValue[][], categories: readonly PlassChartCategory[] | undefined): boolean;
132
184
  /**
133
185
  * The extent of the category values, for a chart whose x is a number.
134
186
  *
@@ -232,8 +284,20 @@ export declare function timeScale(extent: {
232
284
  max?: number;
233
285
  tickCount?: number;
234
286
  }): TimeScale;
235
- /** One instant on a time axis, written unambiguously — for a tooltip or a table. */
236
- export declare function formatTimeValue(value: number, unit: TimeUnit, locale?: string): string;
287
+ /**
288
+ * Whether an axis stepping in hours, minutes or seconds runs over more than one
289
+ * calendar day, and so has to write the date beside each time.
290
+ *
291
+ * `09:00 – 17:00` on an axis two days long could be either day. An axis that
292
+ * ends exactly at midnight has not started the next day, so its last tick does
293
+ * not count on its own.
294
+ */
295
+ export declare function timeNeedsDate(ticks: readonly number[], unit: TimeUnit): boolean;
296
+ /**
297
+ * One instant on a time axis, written unambiguously — for a tooltip or a table.
298
+ * `withDate` puts the date in front of a time, for an axis `timeNeedsDate`.
299
+ */
300
+ export declare function formatTimeValue(value: number, unit: TimeUnit, locale?: string, withDate?: boolean): string;
237
301
  /**
238
302
  * A whole axis of ticks, written the way an axis is read.
239
303
  *
@@ -248,6 +312,10 @@ export declare function formatTimeValue(value: number, unit: TimeUnit, locale?:
248
312
  * one tick a stride never removes. An axis that crosses a year names it on
249
313
  * every tick, so whichever ones survive are each unambiguous. Wider labels mean
250
314
  * a heavier stride, and a heavier stride is the better failure.
315
+ *
316
+ * The date on an axis of hours follows the second rule for the same reason: an
317
+ * axis that crosses midnight writes it on every tick, since the midnight tick
318
+ * is as likely to be dropped as the one a year was riding on.
251
319
  */
252
320
  export declare function formatTimeTicks(ticks: readonly number[], unit: TimeUnit, locale?: string): string[];
253
321
  /**
@@ -305,6 +373,23 @@ export declare function textWidth(text: string, fontSize: number): number;
305
373
  * both still have the whole thing.
306
374
  */
307
375
  export declare function truncate(text: string, maxWidth: number, fontSize: number): string;
376
+ /**
377
+ * The category labels as the axis writes them.
378
+ *
379
+ * A long name is cut to its slot rather than labels being dropped until the
380
+ * rest fit: five categories called "Onboarding flow" would otherwise leave one
381
+ * label on the axis. Once a slot is narrower than about four characters a cut
382
+ * stops helping, and the axis thins its labels out by stride instead. The
383
+ * ticks of a value-scaled axis are numbers already rounded to be short, so they
384
+ * are never cut: half of `12.4K` is not a smaller number, it is a wrong one.
385
+ * The Dart build answers with `fitCategoryLabels`.
386
+ */
387
+ export declare function fitCategoryLabels(texts: string[], options: {
388
+ horizontal: boolean;
389
+ slot: number;
390
+ fontSize: number;
391
+ ticks: boolean;
392
+ }): string[];
308
393
  /** The plot's box inside the chart, once the axes have taken their bands. */
309
394
  export interface PlotBox {
310
395
  left: number;
@@ -471,3 +556,5 @@ export declare function formatCategory(value: PlassChartCategory, locale?: strin
471
556
  * thousands separators stops being welcome.
472
557
  */
473
558
  export declare function compactNumber(value: number, locale?: string): string;
559
+ /** A value as a chart writes it: in the caller's `format`, or compactly without one. */
560
+ export declare function writeChartValue(value: number, format: Intl.NumberFormatOptions | undefined, locale: string | undefined): string;