plass-ui 1.6.0 → 1.8.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 (373) hide show
  1. package/CHANGELOG.md +494 -0
  2. package/README.md +5 -3
  3. package/dist/components/accordion/PlAccordion.d.ts +19 -1
  4. package/dist/components/accordion/PlAccordion.js +1 -1
  5. package/dist/components/accordion/index.d.ts +1 -1
  6. package/dist/components/alert/PlAlert.js +1 -1
  7. package/dist/components/anchor/PlAnchor.js +1 -1
  8. package/dist/components/animate-appear/PlAnimateAppear.js +1 -1
  9. package/dist/components/animate-counter/PlAnimateCounter.d.ts +5 -2
  10. package/dist/components/animate-counter/PlAnimateCounter.js +1 -1
  11. package/dist/components/animate-float/PlAnimateFloat.js +1 -1
  12. package/dist/components/animate-headline/PlAnimateHeadline.d.ts +10 -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 +8 -1
  16. package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -1
  17. package/dist/components/animate-scramble/PlAnimateScramble.js +1 -1
  18. package/dist/components/animate-shake/PlAnimateShake.js +1 -1
  19. package/dist/components/animate-split/PlAnimateSplit.js +1 -1
  20. package/dist/components/animate-typing/PlAnimateTyping.js +1 -1
  21. package/dist/components/app-logo/PlAppLogo.d.ts +51 -15
  22. package/dist/components/app-logo/PlAppLogo.js +1 -1
  23. package/dist/components/area-chart/PlAreaChart.d.ts +35 -6
  24. package/dist/components/area-chart/PlAreaChart.js +1 -1
  25. package/dist/components/aspect-ratio/PlAspectRatio.js +1 -1
  26. package/dist/components/avatar/PlAvatar.js +1 -1
  27. package/dist/components/back-top/PlBackTop.d.ts +5 -5
  28. package/dist/components/back-top/PlBackTop.js +1 -1
  29. package/dist/components/badge/PlBadge.js +1 -1
  30. package/dist/components/bar-chart/PlBarChart.d.ts +54 -2
  31. package/dist/components/bar-chart/PlBarChart.js +1 -1
  32. package/dist/components/blockquote/PlBlockquote.d.ts +2 -2
  33. package/dist/components/blockquote/PlBlockquote.js +1 -1
  34. package/dist/components/bottom-navigation/PlBottomNavigation.d.ts +15 -5
  35. package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -1
  36. package/dist/components/breadcrumb/PlBreadcrumb.d.ts +16 -3
  37. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
  38. package/dist/components/button/PlButton.d.ts +7 -0
  39. package/dist/components/button/PlButton.js +1 -1
  40. package/dist/components/calendar/PlCalendar.js +1 -1
  41. package/dist/components/card/PlCard.d.ts +9 -5
  42. package/dist/components/card/PlCard.js +1 -1
  43. package/dist/components/carousel/PlCarousel.d.ts +14 -4
  44. package/dist/components/carousel/PlCarousel.js +1 -1
  45. package/dist/components/chat-bubble/PlChatBubble.js +1 -1
  46. package/dist/components/checkbox/PlCheckbox.js +1 -1
  47. package/dist/components/chip/PlChip.d.ts +2 -1
  48. package/dist/components/chip/PlChip.js +1 -1
  49. package/dist/components/code-block/PlCodeBlock.js +1 -1
  50. package/dist/components/collapsible/PlCollapsible.d.ts +11 -0
  51. package/dist/components/collapsible/PlCollapsible.js +1 -1
  52. package/dist/components/color-picker/PlColorPicker.d.ts +3 -1
  53. package/dist/components/color-picker/PlColorPicker.js +1 -1
  54. package/dist/components/combobox/PlCombobox.d.ts +11 -5
  55. package/dist/components/combobox/PlCombobox.js +1 -1
  56. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  57. package/dist/components/confirm/PlConfirmProvider.js +1 -1
  58. package/dist/components/data-table/PlDataTable.d.ts +13 -2
  59. package/dist/components/data-table/PlDataTable.js +1 -1
  60. package/dist/components/date-picker/PlDatePicker.js +1 -1
  61. package/dist/components/date-range-picker/PlDateRangePicker.js +1 -1
  62. package/dist/components/date-time-picker/PlDateTimePicker.js +1 -1
  63. package/dist/components/drawer/PlDrawer.d.ts +27 -2
  64. package/dist/components/drawer/PlDrawer.js +1 -1
  65. package/dist/components/empty/PlEmpty.d.ts +4 -1
  66. package/dist/components/empty/PlEmpty.js +1 -1
  67. package/dist/components/fieldset/PlFieldset.js +1 -1
  68. package/dist/components/file-picker/PlFilePicker.d.ts +32 -1
  69. package/dist/components/file-picker/PlFilePicker.js +1 -1
  70. package/dist/components/file-picker/index.d.ts +1 -1
  71. package/dist/components/floating-action-button/PlFloatingActionButton.d.ts +5 -0
  72. package/dist/components/floating-action-button/PlFloatingActionButton.js +1 -1
  73. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.d.ts +10 -0
  74. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
  75. package/dist/components/footer/PlFooter.d.ts +3 -1
  76. package/dist/components/footer/PlFooter.js +1 -1
  77. package/dist/components/gallery/PlGallery.js +1 -1
  78. package/dist/components/gauge-chart/PlGaugeChart.d.ts +11 -2
  79. package/dist/components/gauge-chart/PlGaugeChart.js +1 -1
  80. package/dist/components/header/PlHeader.d.ts +4 -2
  81. package/dist/components/header/PlHeader.js +1 -1
  82. package/dist/components/heatmap-chart/PlHeatmapChart.d.ts +1 -1
  83. package/dist/components/heatmap-chart/PlHeatmapChart.js +1 -1
  84. package/dist/components/hover-card/PlHoverCard.js +1 -1
  85. package/dist/components/how-to-steps/PlHowToSteps.js +1 -1
  86. package/dist/components/image/PlImage.js +1 -1
  87. package/dist/components/image/PlImagePreview.d.ts +3 -2
  88. package/dist/components/line-chart/PlLineChart.d.ts +32 -6
  89. package/dist/components/line-chart/PlLineChart.js +1 -1
  90. package/dist/components/list/PlList.d.ts +16 -5
  91. package/dist/components/list/PlList.js +1 -1
  92. package/dist/components/menu/PlMenu.d.ts +19 -7
  93. package/dist/components/menu/PlMenu.js +1 -1
  94. package/dist/components/menubar/PlMenubar.js +1 -1
  95. package/dist/components/meter/PlMeter.js +1 -1
  96. package/dist/components/mockup/PlMockup.d.ts +6 -0
  97. package/dist/components/mockup/PlMockup.js +1 -1
  98. package/dist/components/modal/PlModal.js +1 -1
  99. package/dist/components/navigation-menu/PlNavigationMenu.d.ts +56 -11
  100. package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
  101. package/dist/components/number-field/PlNumberField.d.ts +7 -5
  102. package/dist/components/number-field/PlNumberField.js +1 -1
  103. package/dist/components/otp-field/PlOtpField.js +1 -1
  104. package/dist/components/overlay/PlOverlay.js +1 -1
  105. package/dist/components/page-layout/PlPageLayout.d.ts +14 -3
  106. package/dist/components/page-layout/PlPageLayout.js +1 -1
  107. package/dist/components/pagination/PlPagination.js +1 -1
  108. package/dist/components/panes/PlPanes.d.ts +4 -1
  109. package/dist/components/panes/PlPanes.js +1 -1
  110. package/dist/components/pie-chart/PlPieChart.d.ts +26 -1
  111. package/dist/components/pie-chart/PlPieChart.js +1 -1
  112. package/dist/components/pill/PlPill.js +1 -1
  113. package/dist/components/popconfirm/PlPopconfirm.d.ts +8 -1
  114. package/dist/components/popconfirm/PlPopconfirm.js +1 -1
  115. package/dist/components/popover/PlPopover.js +1 -1
  116. package/dist/components/progress-box/PlProgressBox.js +1 -1
  117. package/dist/components/progress-circular/PlProgressCircular.d.ts +11 -1
  118. package/dist/components/progress-circular/PlProgressCircular.js +1 -1
  119. package/dist/components/progress-linear/PlProgressLinear.js +1 -1
  120. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  121. package/dist/components/rating/PlRating.js +1 -1
  122. package/dist/components/scatter-chart/PlScatterChart.js +1 -1
  123. package/dist/components/scroll-area/PlScrollArea.js +1 -1
  124. package/dist/components/scroll-zone/PlScrollZone.js +1 -1
  125. package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
  126. package/dist/components/select/PlSelect.d.ts +4 -1
  127. package/dist/components/select/PlSelect.js +1 -1
  128. package/dist/components/sidebar/PlSidebar.d.ts +12 -0
  129. package/dist/components/sidebar/PlSidebar.js +1 -1
  130. package/dist/components/slider/PlSlider.d.ts +2 -1
  131. package/dist/components/slider/PlSlider.js +1 -1
  132. package/dist/components/sparkline/PlSparkline.d.ts +15 -3
  133. package/dist/components/sparkline/PlSparkline.js +1 -1
  134. package/dist/components/stepper/PlStepper.d.ts +11 -0
  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 +11 -1
  138. package/dist/components/table/PlTable.js +1 -1
  139. package/dist/components/tabs/PlTabs.d.ts +18 -1
  140. package/dist/components/tabs/PlTabs.js +1 -1
  141. package/dist/components/text-field/PlTextField.d.ts +6 -8
  142. package/dist/components/text-field/PlTextField.js +1 -1
  143. package/dist/components/text-link/PlTextLink.js +1 -1
  144. package/dist/components/time-picker/PlTimePicker.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.d.ts +4 -0
  149. package/dist/components/tooltip/PlTooltip.js +1 -1
  150. package/dist/components/tour/PlTour.js +1 -1
  151. package/dist/components/transfer/PlTransfer.d.ts +5 -2
  152. package/dist/components/transfer/PlTransfer.js +1 -1
  153. package/dist/components/tree/PlTree.d.ts +12 -0
  154. package/dist/components/tree/PlTree.js +1 -1
  155. package/dist/components/tree-select/PlTreeSelect.js +1 -1
  156. package/dist/components/typography/PlTypography.d.ts +20 -7
  157. package/dist/components/typography/PlTypography.js +1 -1
  158. package/dist/components/visually-hidden/PlVisuallyHidden.d.ts +12 -3
  159. package/dist/components/visually-hidden/PlVisuallyHidden.js +1 -1
  160. package/dist/components/window-pane/PlWindowPane.d.ts +16 -3
  161. package/dist/components/window-pane/PlWindowPane.js +1 -1
  162. package/dist/css/accordion.css +4 -0
  163. package/dist/css/alert.css +5 -0
  164. package/dist/css/anchor.css +6 -0
  165. package/dist/css/animate-appear.css +3 -0
  166. package/dist/css/animate-blink.css +3 -0
  167. package/dist/css/animate-counter.css +4 -0
  168. package/dist/css/animate-fade.css +3 -0
  169. package/dist/css/animate-float.css +3 -0
  170. package/dist/css/animate-grow.css +3 -0
  171. package/dist/css/animate-headline.css +3 -0
  172. package/dist/css/animate-lighting.css +4 -0
  173. package/dist/css/animate-marquee.css +4 -0
  174. package/dist/css/animate-reveal.css +3 -0
  175. package/dist/css/animate-rotate.css +3 -0
  176. package/dist/css/animate-scramble.css +5 -0
  177. package/dist/css/animate-shake.css +3 -0
  178. package/dist/css/animate-slide.css +3 -0
  179. package/dist/css/animate-split.css +4 -0
  180. package/dist/css/animate-typing.css +4 -0
  181. package/dist/css/animate-zoom.css +3 -0
  182. package/dist/css/app-logo.css +2 -0
  183. package/dist/css/area-chart.css +12 -0
  184. package/dist/css/aspect-ratio.css +2 -0
  185. package/dist/css/avatar.css +2 -0
  186. package/dist/css/back-top.css +11 -0
  187. package/dist/css/badge.css +2 -0
  188. package/dist/css/bar-chart.css +10 -0
  189. package/dist/css/base.css +2 -3
  190. package/dist/css/blockquote.css +2 -0
  191. package/dist/css/bottom-navigation.css +4 -0
  192. package/dist/css/box.css +2 -0
  193. package/dist/css/breadcrumb.css +6 -0
  194. package/dist/css/button-group.css +2 -0
  195. package/dist/css/button.css +7 -0
  196. package/dist/css/calendar.css +17 -0
  197. package/dist/css/card.css +2 -0
  198. package/dist/css/carousel.css +10 -0
  199. package/dist/css/chat-bubble.css +6 -0
  200. package/dist/css/checkbox.css +3 -0
  201. package/dist/css/chip.css +8 -0
  202. package/dist/css/code-block.css +6 -0
  203. package/dist/css/collapsible.css +3 -0
  204. package/dist/css/color-picker.css +17 -0
  205. package/dist/css/combobox.css +10 -0
  206. package/dist/css/command-palette.css +7 -0
  207. package/dist/css/confirm.css +9 -0
  208. package/dist/css/container.css +5 -0
  209. package/dist/css/data-list.css +2 -0
  210. package/dist/css/data-table.css +15 -0
  211. package/dist/css/date-picker.css +16 -0
  212. package/dist/css/date-range-picker.css +16 -0
  213. package/dist/css/date-time-picker.css +16 -0
  214. package/dist/css/divider.css +2 -0
  215. package/dist/css/drawer.css +6 -0
  216. package/dist/css/empty.css +2 -0
  217. package/dist/css/fieldset.css +2 -0
  218. package/dist/css/file-picker.css +8 -0
  219. package/dist/css/flex.css +5 -0
  220. package/dist/css/floating-action-button.css +7 -0
  221. package/dist/css/floating-bottom-navigation.css +5 -0
  222. package/dist/css/footer.css +6 -0
  223. package/dist/css/form.css +2 -0
  224. package/dist/css/gallery.css +15 -0
  225. package/dist/css/gauge-chart.css +11 -0
  226. package/dist/css/grid.css +5 -0
  227. package/dist/css/header.css +6 -0
  228. package/dist/css/heatmap-chart.css +10 -0
  229. package/dist/css/highlight.css +2 -0
  230. package/dist/css/hot-keys.css +3 -0
  231. package/dist/css/hover-card.css +9 -0
  232. package/dist/css/how-to-steps.css +3 -0
  233. package/dist/css/icon-button.css +7 -0
  234. package/dist/css/icon.css +1 -0
  235. package/dist/css/image.css +7 -0
  236. package/dist/css/line-chart.css +12 -0
  237. package/dist/css/list.css +2 -0
  238. package/dist/css/menu.css +5 -0
  239. package/dist/css/menubar.css +5 -0
  240. package/dist/css/meter.css +6 -0
  241. package/dist/css/mockup.css +4 -0
  242. package/dist/css/modal.css +5 -0
  243. package/dist/css/navigation-menu.css +4 -0
  244. package/dist/css/number-field.css +10 -0
  245. package/dist/css/otp-field.css +6 -0
  246. package/dist/css/overlay.css +4 -0
  247. package/dist/css/page-layout.css +7 -0
  248. package/dist/css/pagination.css +8 -0
  249. package/dist/css/panes.css +7 -0
  250. package/dist/css/pie-chart.css +10 -0
  251. package/dist/css/pill.css +4 -0
  252. package/dist/css/popconfirm.css +12 -0
  253. package/dist/css/popover.css +11 -0
  254. package/dist/css/portal.css +1 -0
  255. package/dist/css/progress-box.css +5 -0
  256. package/dist/css/progress-circular.css +5 -0
  257. package/dist/css/progress-linear.css +5 -0
  258. package/dist/css/radio-group.css +3 -0
  259. package/dist/css/rating.css +6 -0
  260. package/dist/css/scatter-chart.css +10 -0
  261. package/dist/css/scroll-area.css +2 -0
  262. package/dist/css/scroll-zone.css +15 -0
  263. package/dist/css/segmented-button.css +5 -0
  264. package/dist/css/select.css +9 -0
  265. package/dist/css/show.css +1 -0
  266. package/dist/css/sidebar.css +16 -0
  267. package/dist/css/skeleton.css +2 -0
  268. package/dist/css/slider.css +3 -0
  269. package/dist/css/sparkline.css +10 -0
  270. package/dist/css/spoiler.css +10 -0
  271. package/dist/css/stack.css +5 -0
  272. package/dist/css/stat.css +2 -0
  273. package/dist/css/stepper.css +8 -0
  274. package/dist/css/switch.css +3 -0
  275. package/dist/css/table.css +3 -0
  276. package/dist/css/tabs.css +7 -0
  277. package/dist/css/text-field.css +8 -0
  278. package/dist/css/text-link.css +6 -0
  279. package/dist/css/time-picker.css +16 -0
  280. package/dist/css/timeline-chart.css +10 -0
  281. package/dist/css/timeline.css +6 -0
  282. package/dist/css/toast.css +5 -0
  283. package/dist/css/toggle.css +5 -0
  284. package/dist/css/toolbar.css +2 -0
  285. package/dist/css/tooltip.css +9 -0
  286. package/dist/css/tour.css +10 -0
  287. package/dist/css/transfer.css +13 -0
  288. package/dist/css/tree-select.css +14 -0
  289. package/dist/css/tree.css +3 -0
  290. package/dist/css/visually-hidden.css +2 -0
  291. package/dist/css/window-pane.css +9 -0
  292. package/dist/internal/animate.d.ts +59 -4
  293. package/dist/internal/animate.js +1 -1
  294. package/dist/internal/bottom-bar.d.ts +29 -0
  295. package/dist/internal/bottom-bar.js +1 -0
  296. package/dist/internal/calendar.js +1 -1
  297. package/dist/internal/chart-frame.d.ts +216 -19
  298. package/dist/internal/chart-frame.js +1 -1
  299. package/dist/internal/chart-line.d.ts +11 -6
  300. package/dist/internal/chart-line.js +1 -1
  301. package/dist/internal/chart.d.ts +149 -1
  302. package/dist/internal/chart.js +1 -1
  303. package/dist/internal/commit-change.d.ts +38 -0
  304. package/dist/internal/commit-change.js +1 -0
  305. package/dist/internal/data-table.d.ts +2 -2
  306. package/dist/internal/data-table.js +1 -1
  307. package/dist/internal/date.d.ts +9 -0
  308. package/dist/internal/date.js +1 -1
  309. package/dist/internal/defaults.d.ts +36 -3
  310. package/dist/internal/defaults.js +1 -1
  311. package/dist/internal/direction.d.ts +8 -2
  312. package/dist/internal/direction.js +1 -1
  313. package/dist/internal/focusable.d.ts +10 -0
  314. package/dist/internal/focusable.js +1 -1
  315. package/dist/internal/form.d.ts +72 -0
  316. package/dist/internal/form.js +1 -1
  317. package/dist/internal/format.d.ts +4 -1
  318. package/dist/internal/format.js +1 -1
  319. package/dist/internal/gallery.d.ts +28 -0
  320. package/dist/internal/gallery.js +1 -1
  321. package/dist/internal/glow.d.ts +39 -3
  322. package/dist/internal/glow.js +1 -1
  323. package/dist/internal/heading.d.ts +11 -0
  324. package/dist/internal/heading.js +1 -0
  325. package/dist/internal/highlight.d.ts +4 -2
  326. package/dist/internal/highlight.js +1 -1
  327. package/dist/internal/icons.d.ts +24 -0
  328. package/dist/internal/icons.js +1 -1
  329. package/dist/internal/labels.d.ts +27 -0
  330. package/dist/internal/labels.js +1 -1
  331. package/dist/internal/layout-box.d.ts +35 -0
  332. package/dist/internal/layout-box.js +1 -0
  333. package/dist/internal/lazy.d.ts +37 -0
  334. package/dist/internal/lazy.js +1 -0
  335. package/dist/internal/loading.d.ts +13 -0
  336. package/dist/internal/loading.js +1 -0
  337. package/dist/internal/media.d.ts +6 -0
  338. package/dist/internal/media.js +1 -1
  339. package/dist/internal/mockup.js +1 -1
  340. package/dist/internal/notch.d.ts +57 -3
  341. package/dist/internal/notch.js +1 -1
  342. package/dist/internal/page-layout.d.ts +24 -13
  343. package/dist/internal/page-layout.js +1 -1
  344. package/dist/internal/picker.d.ts +8 -2
  345. package/dist/internal/picker.js +1 -1
  346. package/dist/internal/progress.d.ts +41 -6
  347. package/dist/internal/progress.js +1 -1
  348. package/dist/internal/search.d.ts +12 -0
  349. package/dist/internal/search.js +1 -1
  350. package/dist/internal/sizer.d.ts +18 -10
  351. package/dist/internal/sizer.js +1 -1
  352. package/dist/internal/steps.d.ts +0 -15
  353. package/dist/internal/steps.js +1 -1
  354. package/dist/internal/styles.d.ts +136 -14
  355. package/dist/internal/styles.js +1 -1
  356. package/dist/internal/table-scroll.d.ts +42 -0
  357. package/dist/internal/table-scroll.js +1 -0
  358. package/dist/internal/table.js +1 -1
  359. package/dist/internal/text.d.ts +8 -5
  360. package/dist/internal/wheel.d.ts +13 -1
  361. package/dist/internal/wheel.js +1 -1
  362. package/dist/internal/window.js +1 -1
  363. package/dist/locales/de.js +1 -1
  364. package/dist/locales/es.js +1 -1
  365. package/dist/locales/fr.js +1 -1
  366. package/dist/locales/ja.js +1 -1
  367. package/dist/locales/ko.js +1 -1
  368. package/dist/locales/zh-Hans.js +1 -1
  369. package/dist/styles.css +1 -1
  370. package/dist/tailwind.css +1163 -81
  371. package/dist/tokens.css +1163 -81
  372. package/dist/types.d.ts +226 -13
  373. package/package.json +18 -17
@@ -18,9 +18,9 @@
18
18
  import * as React from 'react';
19
19
  import { type PlBoxProps } from '../components/box/PlBox.js';
20
20
  import { type BandScale, type ChartValue, type PlotBox, type ValueScale } from './chart.js';
21
- import type { PlassChartAxis, PlassChartCategory, PlassChartLegend, PlassChartSeries, PlassChartTooltip, PlassSize } from '../types.js';
21
+ import type { PlassChartAxis, PlassChartCategory, PlassChartLegend, PlassChartReference, PlassChartSeries, PlassChartTooltip, PlassSize } from '../types.js';
22
22
  /**
23
- * How wide the chart actually is, in pixels.
23
+ * How big the chart actually is, in pixels.
24
24
  *
25
25
  * An SVG cannot lay a chart out from a percentage: every tick position, every
26
26
  * bar width and the decision about how many category labels fit are arithmetic
@@ -32,8 +32,32 @@ import type { PlassChartAxis, PlassChartCategory, PlassChartLegend, PlassChartSe
32
32
  * it on a server-rendered page is a box of the right height with nothing in it,
33
33
  * which is why the height is a prop and not something measured too: a reserve
34
34
  * that is dropped when the content arrives is the same jump twice.
35
+ *
36
+ * The height is measured as well, for the one case where the prop does not
37
+ * say it in pixels. A `height` given as a CSS length is laid out by the
38
+ * stylesheet, so the box is already that tall in the server's HTML, and the
39
+ * drawing is laid out at whatever the box comes to. `height` is `null` until
40
+ * the box has been measured.
41
+ *
42
+ * `initialWidth` is the caller's width for the time before there is one. The
43
+ * server's render and the render that hydrates its HTML both lay the chart out
44
+ * at it, so the two agree, and the layout effect after hydration replaces it
45
+ * with the measurement. `guessed` says the width is still the caller's: a chart
46
+ * cuts its drawing at the edge of its box while it is, because a guess wider
47
+ * than the box would otherwise spill across the page until the script runs.
48
+ */
49
+ declare function useMeasuredSize(ref: React.RefObject<HTMLElement | null>, initialWidth?: number): {
50
+ width: number;
51
+ height: number | null;
52
+ guessed: boolean;
53
+ };
54
+ /**
55
+ * The height a chart is drawn at when it is known before the box is measured:
56
+ * the number it was given, or the `size` ladder's when it was given none.
57
+ * `null` for a CSS length, which the box is laid out at and the drawing then
58
+ * measures.
35
59
  */
36
- declare function useMeasuredWidth(ref: React.RefObject<HTMLElement | null>): number;
60
+ declare function givenHeight(height: number | string | undefined, ladder: number): number | null;
37
61
  /**
38
62
  * What every chart takes, and the reason it is one interface: a dashboard is
39
63
  * built by copying a tile and changing the component in it, and that only works
@@ -76,6 +100,10 @@ declare function useMeasuredWidth(ref: React.RefObject<HTMLElement | null>): num
76
100
  * Only the pie and the heatmap ever moved on any of this. The line, the area,
77
101
  * the bar, the scatter and the timeline snapped, and a dashboard holding two of
78
102
  * each showed both answers at once.
103
+ *
104
+ * The declaration is one string literal, however long, because Tailwind finds
105
+ * a class by reading the source text. Pieced together from three strings, it
106
+ * was a class the stylesheet never had, and every mark snapped.
79
107
  */
80
108
  export declare const markTransitionClasses: string;
81
109
  export interface ChartBaseProps extends Omit<PlBoxProps, 'children' | 'title'> {
@@ -83,10 +111,31 @@ export interface ChartBaseProps extends Omit<PlBoxProps, 'children' | 'title'> {
83
111
  * How tall the drawing is. A number is pixels; a string is any CSS length.
84
112
  * Defaults to the `size` ladder.
85
113
  *
114
+ * A string sets the box's height and the drawing is laid out at the height
115
+ * the box is measured at, so on a server, and until the script has run, the
116
+ * box is that tall with nothing drawn in it. A percentage needs a parent
117
+ * whose height is known, as it does anywhere in CSS.
118
+ *
86
119
  * The axis labels are drawn *inside* this, not under it, so a card sized to
87
120
  * the chart is a card the chart fits in.
88
121
  */
89
122
  height?: number | string;
123
+ /**
124
+ * The width to draw at until the box has been measured, in pixels.
125
+ *
126
+ * A chart is laid out from the width its box is measured at, and a server
127
+ * has no box to measure: without this, the HTML it sends holds an empty box
128
+ * of the right height and the plot arrives with the script. Given the width
129
+ * the chart usually has, the server and the render that hydrates its HTML
130
+ * draw the whole chart at it, and the measured width takes over before the
131
+ * hydrated page is painted. Until then a drawing wider than its box is cut
132
+ * at the box's edge. A `height` given as a CSS length is not known until the
133
+ * box is measured either, so with one the server draws the box alone.
134
+ *
135
+ * A page rendered only in the browser measures the box before its first
136
+ * paint, so it never shows this width.
137
+ */
138
+ initialWidth?: number;
90
139
  /**
91
140
  * How the numbers are written, everywhere they appear — the axis, the
92
141
  * tooltip, the labels on the marks. `Intl.NumberFormat` options, the same
@@ -101,6 +150,12 @@ export interface ChartBaseProps extends Omit<PlBoxProps, 'children' | 'title'> {
101
150
  /**
102
151
  * The chart's accessible name — what it is a chart *of*. Read out in place of
103
152
  * the drawing, and used as the caption of the table underneath it.
153
+ *
154
+ * It is not text anybody sees, so an `aria-label` names the drawing in its
155
+ * place, as one names a control in its visible label's, and an
156
+ * `aria-labelledby` outranks both. The table is named by whichever of the
157
+ * three names the drawing: a reference points it at the same element, and
158
+ * words are its caption.
104
159
  */
105
160
  label?: string;
106
161
  /**
@@ -133,21 +188,53 @@ export interface CartesianChartProps extends ChartBaseProps {
133
188
  xAxis?: PlassChartAxis;
134
189
  /** The value axis. */
135
190
  yAxis?: PlassChartAxis;
191
+ /**
192
+ * Lines drawn across the plot at a value — a target, an average, a limit.
193
+ *
194
+ * Not data, and drawn as if they know it: dashed, in the muted ink, under the
195
+ * marks. They sit on the **value** axis, so one runs across a vertical chart
196
+ * and down a horizontal one. Each is written into the description a screen
197
+ * reader is given with the chart.
198
+ */
199
+ reference?: PlassChartReference | readonly PlassChartReference[];
136
200
  }
137
201
  interface Visibility {
202
+ /** The key each series' legend entry is rendered under, from `entryKeys`. */
203
+ keys: readonly string[];
138
204
  visible: boolean[];
139
205
  hovered: number | null;
140
206
  toggle: (index: number) => void;
141
207
  setHovered: (index: number | null) => void;
142
208
  }
209
+ /**
210
+ * The keys the legend entries of `series` are rendered under, one per series
211
+ * and in its order: its `id` and how many series before it have that id, or
212
+ * else its name and how many series before it have that name, or its place in
213
+ * the array when it has neither.
214
+ *
215
+ * No two entries share a key. Every name is followed by its count and a place
216
+ * never is: two series called "Revenue" are `Revenue#0` and `Revenue#1`, and a
217
+ * series called "1" is `1#0` where an unnamed one at index 1 is `1`. The count
218
+ * is whatever follows the last `#`, so a name holding a `#` of its own cannot
219
+ * meet another name's key either. An id is followed by its count and then by
220
+ * `@id`, so a series with the id "eu" is `eu#0@id`, which ends in a letter
221
+ * where the key of a name or of a place always ends in a digit.
222
+ *
223
+ * A timeline keys its rows with it as well. They have no legend, but a mark on
224
+ * one is held by its row's key, as a mark on a series is held by its entry's.
225
+ */
226
+ declare function entryKeys(series: readonly Pick<PlassChartSeries, 'id' | 'name'>[]): string[];
143
227
  /**
144
228
  * Which series are drawn, and which one the pointer is resting on in the legend.
145
229
  *
146
- * Keyed by index into the array as it was passed, which is what keeps a hidden
147
- * series from renumbering the ones after it. The colours come off the same
148
- * index, so hiding Europe leaves Asia exactly the colour it was.
230
+ * Answered by index into the array as it was passed, which is what keeps a
231
+ * hidden series from renumbering the ones after it. The colours come off the
232
+ * same index, so hiding Europe leaves Asia exactly the colour it was.
233
+ *
234
+ * `listed` is whether the legend is drawn with entries that answer the pointer
235
+ * and the focus, which is where the hovered one comes from.
149
236
  */
150
- declare function useVisibility(series: readonly PlassChartSeries[]): Visibility;
237
+ declare function useVisibility(series: readonly PlassChartSeries[], listed: boolean): Visibility;
151
238
  interface LegendProps {
152
239
  series: readonly PlassChartSeries[];
153
240
  colors: readonly string[];
@@ -156,6 +243,8 @@ interface LegendProps {
156
243
  size: PlassSize;
157
244
  values?: readonly (string | undefined)[];
158
245
  swatch?: (index: number, color: string) => React.ReactNode;
246
+ /** Which entries are drawn on the plot as a dashed line, by index. */
247
+ dashed?: readonly boolean[];
159
248
  }
160
249
  /**
161
250
  * The dependable identity channel.
@@ -165,15 +254,20 @@ interface LegendProps {
165
254
  * light hue is illegible as text and because colour is what the swatch beside
166
255
  * it is for.
167
256
  *
168
- * A hidden series stays in the legend and goes grey rather than disappearing:
169
- * a list that shortens when you click it is a list you cannot click twice.
257
+ * A hidden series stays in the legend and fades rather than disappearing: a
258
+ * list that shortens when you click it is a list you cannot click twice. It
259
+ * fades as one thing — swatch, name and value together, at one opacity — which
260
+ * is what a control that has been switched off looks like everywhere else in
261
+ * the library. Recolouring the name to the muted ink instead was the one place
262
+ * a hidden entry was told apart by a *hue*, and it read as a second kind of
263
+ * text rather than as the same entry, off.
170
264
  *
171
265
  * `swatch` is for the chart whose marks carry a second identity channel. A
172
266
  * scatter past the third series tells its series apart by shape as well as by
173
267
  * hue, and a legend that answered with eight identical squares would be back to
174
268
  * colour alone — which is the thing the shapes were added to fix.
175
269
  */
176
- declare function ChartLegendBar({ series, colors, options, visibility, size, values, swatch }: LegendProps): React.JSX.Element;
270
+ declare function ChartLegendBar({ series, colors, options, visibility, size, values, swatch, dashed }: LegendProps): React.JSX.Element;
177
271
  interface ScaleLegendProps {
178
272
  /** The steps, palest first, as the `var()`s that resolve them. */
179
273
  steps: readonly string[];
@@ -209,6 +303,13 @@ export interface ChartTooltipItem {
209
303
  value: number | null;
210
304
  formatted: string;
211
305
  label?: React.ReactNode;
306
+ /**
307
+ * A second figure, written after the reading in brackets: a bubble's size,
308
+ * as in `22 (5)`. Kept apart from `formatted` and `label` so that what a
309
+ * caller's own `tooltip.render` is handed is still the value and the point's
310
+ * own words.
311
+ */
312
+ aside?: string;
212
313
  }
213
314
  interface TooltipProps {
214
315
  heading: React.ReactNode;
@@ -251,9 +352,26 @@ declare function ChartStatus({ heading, items }: {
251
352
  heading?: React.ReactNode;
252
353
  items: readonly ChartTooltipItem[];
253
354
  }): React.JSX.Element;
254
- interface DataTableProps {
255
- id: string;
355
+ /** What the table under a chart is called. See `chartTableName`. */
356
+ interface ChartTableName {
357
+ /** The words it is captioned with: an `aria-label`, else `label`. */
256
358
  caption?: string;
359
+ /** A caller's `aria-labelledby`, which names it in place of a caption. */
360
+ labelledBy?: string;
361
+ }
362
+ /**
363
+ * What the table under a chart is called, by the precedence its picture is
364
+ * called by: a caller's `aria-labelledby`, then an `aria-label` in `label`'s
365
+ * place, then `label`.
366
+ *
367
+ * A reference names the table by the same element it names the picture by,
368
+ * and leaves it no caption, whose words would be read inside the table as a
369
+ * name nobody gave it. Words are its caption, as `label` always was. With
370
+ * none of the three the table has no name, as before.
371
+ */
372
+ declare function chartTableName({ label, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy }: Pick<ChartBaseProps, 'label' | 'aria-label' | 'aria-labelledby'>): ChartTableName;
373
+ interface DataTableProps extends ChartTableName {
374
+ id: string;
257
375
  corner?: React.ReactNode;
258
376
  categories: readonly PlassChartCategory[];
259
377
  series: readonly PlassChartSeries[];
@@ -261,7 +379,24 @@ interface DataTableProps {
261
379
  format: (value: number) => string;
262
380
  locale?: string;
263
381
  }
264
- declare const ChartDataTable: React.MemoExoticComponent<({ id, caption, corner, categories, series, values, format, locale }: DataTableProps) => React.JSX.Element>;
382
+ /**
383
+ * The chart, as a table, for the readers a drawing does not reach.
384
+ *
385
+ * Not an option and not a toggle. A tooltip that is the only way to a number
386
+ * gates that number behind a pointer, and an SVG with an `aria-label` on it
387
+ * says "revenue by month" and then says nothing else at all. This is the same
388
+ * data in the one form every assistive technology already reads, so the picture
389
+ * is free to be a picture.
390
+ *
391
+ * It is clipped rather than `display: none`, for the reason `srOnlyClasses`
392
+ * gives: the second one takes it off the accessibility tree along with the
393
+ * screen, which would leave the chart exactly as mute as before.
394
+ *
395
+ * Memoised, because it is a row for every category and none of it changes when
396
+ * the pointer or a key moves the active column, which re-renders the chart
397
+ * around it every time.
398
+ */
399
+ declare const ChartDataTable: React.MemoExoticComponent<({ id, caption, labelledBy, corner, categories, series, values, format, locale }: DataTableProps) => React.JSX.Element>;
265
400
  interface SurfaceProps extends Omit<PlBoxProps, 'children'> {
266
401
  legend: React.ReactNode;
267
402
  legendSide: NonNullable<PlassChartLegend['side']>;
@@ -284,6 +419,13 @@ export interface ChartMark {
284
419
  series: number;
285
420
  /** Its own place within that series. */
286
421
  index: number;
422
+ /**
423
+ * What its series is known by, from `entryKeys`, when the chart's series are
424
+ * not the frame's: a timeline's rows, which the frame is handed as its
425
+ * categories. Without it, the mark's series is known by its legend entry's
426
+ * key.
427
+ */
428
+ key?: string;
287
429
  /** Its centre, in pixels from the chart's top-left. */
288
430
  x: number;
289
431
  y: number;
@@ -345,6 +487,11 @@ export interface CartesianLayout {
345
487
  categoryValuePx: (value: number) => number;
346
488
  /** Where the baseline is along the value axis. */
347
489
  zeroPx: number;
490
+ /**
491
+ * How tall the drawing is, in pixels: the `height` asked for, or the height
492
+ * the box was measured at when that was a CSS length.
493
+ */
494
+ height: number;
348
495
  categories: readonly PlassChartCategory[];
349
496
  format: (value: number) => string;
350
497
  size: PlassSize;
@@ -360,6 +507,15 @@ export interface CartesianContext extends CartesianLayout {
360
507
  /** The one the pointer is on, or the one the arrow keys walked to. */
361
508
  activeMark: ChartMark | null;
362
509
  }
510
+ /**
511
+ * One line of the summary a screen reader is handed: a series and its end, or
512
+ * a timeline's row and the stretch of time it covers.
513
+ */
514
+ interface ChartSummaryEntry {
515
+ name: string;
516
+ /** What the series ended on, or `null` for a series that is all gaps. */
517
+ said: React.ReactNode | null;
518
+ }
363
519
  interface CartesianProps extends CartesianChartProps {
364
520
  /**
365
521
  * Makes the category axis a second value axis instead of a row of columns.
@@ -380,10 +536,37 @@ interface CartesianProps extends CartesianChartProps {
380
536
  * @default 24
381
537
  */
382
538
  markRadius?: number;
383
- /** The table under the chart, for a chart whose data is not a grid. */
384
- table?: (id: string) => React.ReactNode;
539
+ /**
540
+ * The table under the chart, for a chart whose data is not a grid. Handed
541
+ * the id it is referred to by and what it is called.
542
+ */
543
+ table?: (id: string, name: ChartTableName) => React.ReactNode;
544
+ /**
545
+ * What a screen reader is handed in place of the drawing, for a chart whose
546
+ * series are not what it is about. A timeline hands the frame one stand-in
547
+ * series for its rows, and "each series and where it ended" would read that
548
+ * series out as a number nobody wrote. The reference lines still follow it.
549
+ */
550
+ summary?: readonly ChartSummaryEntry[];
551
+ /**
552
+ * How a value on the value axis is written wherever the frame writes one
553
+ * itself, in place of `format`: a reference line in the description, for
554
+ * one. A timeline's value axis is a calendar, and an instant written as a
555
+ * number is a count of milliseconds nobody reads.
556
+ */
557
+ writeValue?: (value: number) => string;
385
558
  /** The legend's swatch, for a chart whose marks are not all the same shape. */
386
559
  swatch?: (index: number, color: string) => React.ReactNode;
560
+ /**
561
+ * The marks are a stroke along the categories — a line, or the edge of an
562
+ * area that is not stacked — so a `dashed` series is drawn dashed, and its
563
+ * legend entry is a dashed rule rather than a square.
564
+ *
565
+ * Said by the chart rather than read off the series, because `dashed` does
566
+ * nothing on a bar or a stacked band, and a legend that promised a dashed line
567
+ * the plot never drew would be the one part of the chart that lied.
568
+ */
569
+ stroked?: boolean;
387
570
  /**
388
571
  * The value axis' scale, already worked out.
389
572
  *
@@ -400,10 +583,21 @@ interface CartesianProps extends CartesianChartProps {
400
583
  * for anything whose marks sit in a grid the frame already understands. A
401
584
  * Gantt's rows are the frame's *categories* and its marks are spans within
402
585
  * them, so there is no cell for the frame to look the answer up in.
586
+ *
587
+ * `index` and `category` are what a caller's own `tooltip.render` is handed,
588
+ * when the mark's own place is not them. A span sits in its row, which is the
589
+ * category, and the mark's `index` is the span's place along that row.
590
+ * `renderItems` is handed in place of `items` when the card's rows are not
591
+ * what a caller should be handed: the card names a span's row beside the
592
+ * swatch, and a caller who is already handed the row as `category` wants the
593
+ * span's own name there instead.
403
594
  */
404
595
  markTooltip?: (mark: ChartMark) => {
405
596
  heading: React.ReactNode;
406
597
  items: readonly ChartTooltipItem[];
598
+ index?: number;
599
+ category?: PlassChartCategory;
600
+ renderItems?: readonly ChartTooltipItem[];
407
601
  } | null;
408
602
  /** Bars, and only bars, run the other way. */
409
603
  horizontal?: boolean;
@@ -429,8 +623,11 @@ interface CartesianProps extends CartesianChartProps {
429
623
  * A line's marker gets away with it because a line is inset from both ends
430
624
  * anyway; a scatter places a mark wherever the number says, including exactly
431
625
  * on the corner.
626
+ *
627
+ * A function is handed the height the chart is drawn at, for a reserve that
628
+ * is a share of it.
432
629
  */
433
- markInset?: number;
630
+ markInset?: number | ((height: number) => number);
434
631
  /** Draws the marks. */
435
632
  children: (context: CartesianContext) => React.ReactNode;
436
633
  }
@@ -442,6 +639,6 @@ interface CartesianProps extends CartesianChartProps {
442
639
  * function's business, and they are handed pixels rather than values so a
443
640
  * component never has to know which way round the axes are.
444
641
  */
445
- export declare function CartesianChart({ series, categories, xAxis, yAxis, horizontal, stacked, includeZero, bandRatio, inset, headroom, markInset, xScale, marks, markRadius, table, swatch, scale: givenScale, markTooltip, height, format, locale: localeProp, label, legend, tooltip, empty, size: sizeProp, variant, padded, className, children, ...box }: CartesianProps): React.JSX.Element;
446
- export { ChartDataTable, ChartLegendBar, ChartScaleLegend, ChartStatus, ChartSurface, ChartTooltipPanel, useMeasuredWidth, useVisibility };
447
- export type { Visibility };
642
+ export declare function CartesianChart({ series, categories, xAxis, yAxis, reference, horizontal, stacked, includeZero, bandRatio, inset, headroom, markInset: markInsetProp, xScale, marks, markRadius, table, summary: givenSummary, writeValue, swatch, stroked, scale: givenScale, markTooltip, height, initialWidth, format, locale: localeProp, label, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, legend, tooltip, empty, size: sizeProp, variant, padded, className, children, ...box }: CartesianProps): React.JSX.Element;
643
+ export { ChartDataTable, ChartLegendBar, ChartScaleLegend, ChartStatus, ChartSurface, ChartTooltipPanel, chartTableName, entryKeys, givenHeight, useMeasuredSize, useVisibility };
644
+ export type { ChartSummaryEntry, ChartTableName, Visibility };
@@ -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,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
+ "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 i,categoryAt as s,categoryCount as r,categoriesAreDates as o,categoryExtent as d,chartFontSizes as c,compactNumber as u,extentOf as h,fitCategoryLabels as m,fitsLast as p,formatCategory as f,formatTimeTicks as x,lineDash as g,lineWidths as v,logScale as y,markerRadii as b,plotHeights as k,resolveColor as w,seriesColor as M,autoTickAngle as N,showsTick as z,textWidth as C,tickAngleOf as S,tickStride as A,tiltedDepth as $,tiltedPitch as P,tiltedRoom as j,tiltedStep as B,toValues as T,truncate as W,timeScale as _,valueScale as I,writeChartValue as D}from"./chart.js";import{useDefaults as E,useLocale as F}from"./defaults.js";import{usePlElementSize as K}from"../hooks/usePlElementSize.js";import{useLabels as H}from"./labels.js";import{layoutBox as L}from"./layout-box.js";import{textOf as R}from"./text.js";import{cx as V,glassClasses as Z,hasContent as O,metaTextClasses as U,srOnlyClasses as X,transitionClasses as Y}from"./styles.js";const q=[];function useMeasuredSize(e,t){const l=K(e);if(null!==l)return{width:l.width,height:l.height,guessed:!1};const a=void 0!==t&&Number.isFinite(t)&&t>0?t:0;return{width:a,height:null,guessed:a>0}}function givenHeight(e,t){return"number"==typeof e?e:void 0===e?t:null}export const markTransitionClasses=/* @__PURE__ */["[transition:opacity_var(--plass-duration)_var(--plass-ease),r_var(--plass-duration)_var(--plass-ease),scale_var(--plass-duration)_var(--plass-ease)]","motion-reduce:[transition-duration:0ms]"].join(" ");function entryKeys(e){const t=new Map,l=new Map;return e.map((e,a)=>{const n=e.id??null;if(null!==n){const e=l.get(n)??0;return l.set(n,e+1),`${n}#${e}@id`}const i=e.name??null;if(null===i)return String(a);const s=t.get(i)??0;return t.set(i,s+1),`${i}#${s}`})}function useVisibility(e,t){const l=entryKeys(e),[n,i]=a.useState(()=>{const t=new Set;return e.forEach((e,a)=>{e.hidden&&t.add(l[a])}),t});[...n].some(e=>!l.includes(e))&&i(new Set([...n].filter(e=>l.includes(e))));const[s,r]=a.useState(null),o=null!==s&&t?l.indexOf(s):-1;return null!==s&&-1===o&&r(null),{keys:l,visible:l.map(e=>!n.has(e)),hovered:-1===o?null:o,toggle:e=>{const t=l[e];void 0!==t&&i(e=>{const l=new Set(e);return l.has(t)?l.delete(t):l.add(t),l})},setHovered:e=>r(null===e?null:l[e]??null)}}const G={top:"flex-col-reverse",bottom:"flex-col",left:"flex-row-reverse rtl:flex-row",right:"flex-row rtl:flex-row-reverse"},J={start:"justify-start",center:"justify-center",end:"justify-end"};function DashedRule({ink:t,size:l}){const a=v[l],n=16+a;return e("svg",{"aria-hidden":"true",width:n,height:10,viewBox:`0 0 ${n} 10`,className:"block shrink-0",children:e("line",{x1:a/2,x2:n-a/2,y1:5,y2:5,stroke:t,strokeWidth:a,strokeDasharray:g,strokeLinecap:"round"})})}function ChartLegendBar({series:n,colors:i,options:s,visibility:r,size:o,values:d,swatch:c,dashed:u}){const h=!1!==s.interactive,m="left"===s.side||"right"===s.side,p=H(),[f,x]=a.useState(!1),g=s.maxEntries,v=void 0!==g&&g>0&&n.length>g&&!f,y=v?n.slice(0,g):n,b=n.length-y.length,k=entryKeys(n);return l("ul",{className:V("m-0 flex list-none flex-wrap items-center gap-x-3 gap-y-1 p-0",m?"min-w-0 flex-col items-start":"",J[s.align??"center"],U[o]),children:[y.map((a,n)=>{const s=r.visible[n],m=null!==r.hovered&&r.hovered!==n,p=a.name??`${n+1}`,f=i[n],x=s?m?"opacity-55":"":"opacity-40",g=l(t,{children:[c?e("span",{"aria-hidden":"true",className:"flex size-2.5 shrink-0 items-center justify-center",children:c(n,f)}):u?.[n]?e(DashedRule,{ink:f,size:o}):e("span",{"aria-hidden":"true",className:`size-2.5 shrink-0 rounded-[0.1875rem] ${Y}`,style:{backgroundColor:f}}),e("span",{className:"min-w-0 truncate",children:p}),d?.[n]?e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:d[n]}):null]});return e("li",{className:"min-w-0",children:h?e("button",{type:"button","aria-pressed":s,onClick:()=>r.toggle(n),onPointerEnter:()=>r.setHovered(n),onPointerLeave:()=>r.setHovered(null),onFocus:()=>r.setHovered(n),onBlur:()=>r.setHovered(null),className:V("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)]","motion-reduce:[transition-duration:0ms]","hover:bg-(--p-soft)","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-1",s?"":"line-through",x),children:g}):e("span",{className:V("flex min-w-0 items-center gap-1.5 px-1 py-0.5 text-(--plass-fg)",s?"":"line-through",x),children:g})},k[n])}),v||f?e("li",{className:"min-w-0",children:e("button",{type:"button","aria-expanded":f,onClick:()=>x(e=>!e),className:V("flex cursor-pointer items-center rounded-(--plass-radius-xs)","px-1 py-0.5 font-medium text-(--plass-muted-fg)","[transition-property:background-color,color]","[transition-duration:var(--plass-duration)]","[transition-timing-function:var(--plass-ease)]","motion-reduce:[transition-duration:0ms]","hover:bg-(--p-soft) hover:text-(--plass-fg)","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-1"),children:f?p.chartFewer:p.chartMore(b)})}):null]})}function ChartScaleLegend({steps:a,from:n,to:i,middle:s,align:r,vertical:o,size:d}){return e("div",{className:V("flex",o?"":J[r]),children:l("div",{className:V("grid grid-cols-[auto_auto_auto] items-center gap-x-2",U[d]),children:[e("span",{className:"shrink-0 tabular-nums text-(--plass-muted-fg)",children:n}),e("span",{"aria-hidden":"true",className:V("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:i}),s?l(t,{children:[e("span",{}),e("span",{className:"text-center tabular-nums text-(--plass-muted-fg)",children:s}),e("span",{})]}):null]})})}function itemText(e){const a=e.label??e.formatted;return void 0===e.aside?a:l(t,{children:[a," (",e.aside,")"]})}function ChartTooltipPanel({heading:t,items:a,x:n,y:i,flip:s,size:r}){return l("div",{"data-plass-tooltip":"",className:V("pointer-events-none absolute z-10 max-w-56 min-w-24","rounded-(--plass-radius-sm) border p-2",Z,"bg-(--plass-glass-press) [border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]",U[r]),style:s?{right:`calc(100% - ${n}px + 10px)`,top:i}:{left:n+10,top:i},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:itemText(t)})]},t.seriesIndex))})]})}function ChartStatus({heading:n,items:i}){return e("span",{role:"status","aria-live":"polite",className:X,children:0===i.length?null:l(t,{children:[O(n)?l(t,{children:[n,", "]}):null,i.map((e,t)=>l(a.Fragment,{children:[t>0?", ":null,e.name?`${e.name}: `:null,itemText(e)]},e.seriesIndex))]})})}function chartTableName({label:e,"aria-label":t,"aria-labelledby":l}){return l?{labelledBy:l}:{caption:t??e}}const Q=/* @__PURE__ */a.memo(function ChartDataTable({id:t,caption:a,labelledBy:n,corner:i,categories:s,series:r,values:o,format:d,locale:c}){const u=entryKeys(r);return l("table",{id:t,className:X,"aria-labelledby":n,children:[a?e("caption",{children:a}):null,e("thead",{children:l("tr",{children:[e("th",{scope:"col",children:i??""}),r.map((t,l)=>e("th",{scope:"col",children:t.name??l+1},u[l]))]})}),e("tbody",{children:s.map((t,a)=>l("tr",{children:[e("th",{scope:"row",children:f(t,c)}),u.map((t,l)=>{const n=o[l]?.[a];return e("td",void 0!==n?.label?{children:n.label}:{children:null==n?.value?"":d(n.value)},t)})]},a))})]})});function ChartSurface({legend:t,legendSide:a,children:i,table:s,className:r,...o}){return l(n,{...o,className:V("relative flex gap-3",G[a],r??void 0),children:[e("div",{className:"relative min-w-0 flex-1",children:i}),t,s]})}function markKey(e,t){return`${e.key??t[e.series]??e.series}:${e.index}`}export function CartesianChart({series:n,categories:p,xAxis:g,yAxis:v,reference:w,horizontal:z=!1,stacked:A=!1,includeZero:P=!0,bandRatio:K=1,inset:Z=!1,headroom:O=0,markInset:Y=0,xScale:G="band",marks:J,markRadius:ee=24,table:te,summary:le,writeValue:ae,swatch:ne,stroked:ie=!1,scale:se,markTooltip:re,height:oe,initialWidth:de,format:ce,locale:ue,label:he,"aria-label":me,"aria-labelledby":pe,"aria-describedby":fe,legend:xe,tooltip:ge,empty:ve,size:ye,variant:be="ghost",padded:ke=!1,className:we,children:Me,...Ne}){const ze=E(),Ce=ye??ze.size??"md",Se=F(ue),Ae=a.useRef(null),{width:$e,height:Pe,guessed:je}=useMeasuredSize(Ae,de),Be=a.useRef({key:"",across:1,down:1}),Te=H(),We=a.useId(),_e=a.useId(),Ie=a.useId(),De=!1===xe?{interactive:!1}:!0===xe||void 0===xe?{}:xe,Ee=!0===xe||!1!==xe&&n.length>1,Fe=De.side??"bottom",Ke=useVisibility(n,Ee&&!1!==De.interactive),[He,Le]=a.useState(null),[Re,Ve]=a.useState(null),[Ze,Oe]=a.useState(null),Ue=a.useCallback(e=>ae?ae(e):D(e,ce,Se),[ae,ce,Se]),Xe=a.useMemo(()=>T(n),[n]),Ye=a.useMemo(()=>n.map((e,t)=>M(e,t)),[n]),qe=a.useMemo(()=>n.map(e=>!0===e.dashed),[n]),Ge=r(n),Je=a.useMemo(()=>Array.from({length:Ge},(e,t)=>s(t,p,Xe)),[Ge,p,Xe]),Qe=Xe.filter((e,t)=>Ke.visible[t]),et=h(Qe,A),tt=a.useMemo(()=>le??n.flatMap((e,t)=>{if(!Ke.visible[t])return[];const l=[...Xe[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??Ue(l.value)}]}),[le,n,Xe,Ke.visible,Ue]),lt=givenHeight(oe,k[Ce]),at=c[Ce],nt=v,it=g,st=a.useMemo(()=>void 0===w?[]:Array.isArray(w)?w:[w],[w]),rt=se??("log"===nt?.scale?y(et,{min:nt.min,max:nt.max,tickCount:nt.tickCount}):I(et,{min:nt?.min,max:nt?.max,tickCount:nt?.tickCount,includeZero:P})),ot="value"===G?d(Qe,p):null,dt="value"===G&&o(Xe,p),ct="value"!==G?null:dt?_(ot,{min:it?.min,max:it?.max,tickCount:it?.tickCount}):"log"===it?.scale?y(ot,{min:it.min,max:it.max,tickCount:it.tickCount}):I(ot,{min:it?.min,max:it?.max,tickCount:it?.tickCount,includeZero:!1}),ut=ct&&"unit"in ct?x(ct.ticks,ct.unit,Se):null,ht=rt.ticks.map((e,t)=>nt?.tickFormat?R(nt.tickFormat(e,t)):Ue(e)),mt=it?.tickFormat,pt=a.useMemo(()=>Je.map((e,t)=>mt?R(mt(e,t)):f(e,Se)),[Je,mt,Se]),ft=ct?ct.ticks.map((e,t)=>mt?R(mt(dt?new Date(e):e,t)):ut?.[t]??u(e,Se)):pt,xt=ht.reduce((e,t)=>Math.max(e,C(t,at)),0),gt=at+6,vt=nt?.hidden?0:xt+10+(nt?.label?gt:0),yt=($e-(z?0:vt)-16)/Math.max(1,Ge),bt=lt??Pe??0,kt="function"==typeof Y?Y(bt):Y,wt=null!==ct,Mt=it?.tickAngle,Nt=z?0:"auto"===Mt?wt?0:N(ft,{slot:yt,fontSize:at}):S(Mt),zt=0!==Nt&&!it?.hidden,Ct=Math.max(3*at,.4*bt),St=a.useMemo(()=>zt?ft.map(e=>W(e,j(Ct,Nt,at),at)):m(ft,{horizontal:z,slot:yt,fontSize:at,ticks:wt}),[ft,zt,Ct,Nt,z,yt,at,wt]),At=a.useMemo(()=>St.reduce((e,t)=>Math.max(e,C(t,at)),0),[St,at]),$t=zt?B(At,Nt,at)+4:0,Pt=z?it?.hidden?0:At+10+(it?.label?gt:0):vt,jt=z?nt?.hidden?0:at+12+(nt?.label?gt:0):it?.hidden?0:(zt?$(At,Nt,at)+14:at+12)+(it?.label?gt:0),Bt=Math.max((z?it:nt)?.thickness??Pt,zt&&Nt<0?$t:0),Tt=(z?nt:it)?.thickness??jt,Wt=(z?12:zt?Nt>0?$t:12:ct?12:Math.max(8,St.length?At/2:8))+kt,_t=b[Ce]+4+O+kt,It={left:Bt+kt,top:_t,width:Math.max(0,$e-Bt-kt-Wt),height:Math.max(0,bt-_t-Tt-kt)},Dt=z?It.height:It.width,Et=i(Z?Math.max(1,Ge-1):Ge,Dt,K),Ft=a.useCallback(e=>Z?Ge<=1?Dt/2:Dt*e/(Ge-1):Et.centre(e),[Z,Ge,Dt,Et]),Kt=a.useCallback(e=>z?It.left+rt.fraction(e)*It.width:It.top+(1-rt.fraction(e))*It.height,[z,It.left,It.top,It.width,It.height,rt]),Ht=a.useCallback((e,t)=>z?{x:Kt(t),y:It.top+Ft(e)}:{x:It.left+Ft(e),y:Kt(t)},[z,Kt,Ft,It.left,It.top]),Lt=a.useCallback(e=>z?It.top+(1-(ct?.fraction(e)??0))*It.height:It.left+(ct?.fraction(e)??0)*It.width,[z,It.left,It.top,It.width,It.height,ct]),Rt=Kt(Math.min(Math.max(0,rt.min),rt.max)),Vt={plot:It,values:Xe,visible:Ke.visible,colors:Ye,dashed:qe,scale:rt,band:Et,horizontal:z,valuePx:Kt,categoryPx:Ft,point:Ht,categoryScale:ct,categoryValuePx:Lt,zeroPx:Rt,height:bt,categories:Je,format:Ue,size:Ce},Zt=!1===ge?{mode:"none"}:!0===ge||void 0===ge?{}:ge,Ot=Zt.mode??(J?"item":"index"),Ut=J??("nearest"===Ot?e=>function gridMarks(e,t){const l=[],a=b[e.size],n=[];return e.values.forEach((i,s)=>{const r=i.map((e,t)=>n[t]??0);t&&e.visible[s]&&i.forEach((e,t)=>{n[t]=(n[t]??0)+(e.value??0)}),e.visible[s]&&i.forEach((n,i)=>{if(null===n.value)return;const o=e.point(i,t?r[i]+n.value:n.value);l.push({series:s,index:i,x:o.x,y:o.y,r:a})})}),l}(e,A):void 0),Xt=Ut?Ut(Vt):q,Yt=null===Re?-1:Xt.findIndex(e=>markKey(e,Ke.keys)===Re),qt=-1===Yt?null:Xt[Yt],Gt=Ut?qt?qt.index:null:He,Jt=Ut?Xt.length:Ge,clearActive=()=>{Le(null),Ve(null),Oe(null)};(null!==He&&He>=Ge||null!==Re&&!qt)&&clearActive();const goTo=e=>{const t=null===e?null:Math.min(Jt-1,Math.max(0,e));if(Oe(null),Ut){const e=null===t?void 0:Xt[t];Ve(e?markKey(e,Ke.keys):null)}else Le(t)},step=e=>{goTo(((Ut?-1===Yt?null:Yt:He)??(e>0?-1:Jt))+e)},Qt=null===Gt?[]:n.flatMap((e,t)=>{if(!Ke.visible[t]||qt&&qt.series!==t)return[];const l=Xe[t]?.[Gt];return l&&null!==l.value?[{seriesIndex:t,name:e.name,color:l.color??Ye[t],value:l.value,formatted:Ue(l.value),label:l.label}]:[]}),el=qt&&re?re(qt):null,tl=el?el.items:"item"===Ot&&Qt.length>1&&null!==Ze?[Qt.reduce((e,t)=>Math.abs(Kt(t.value??0)-Ze)<Math.abs(Kt(e.value??0)-Ze)?t:e)]:Qt,ll=qt?Xe[qt.series]?.[qt.index]?.x??p?.[qt.index]??qt.index:void 0,al=qt?qt.x:z?Kt(tl[0]?.value??0):It.left+Ft(Gt??0),nl=qt?qt.y:z?It.top+Ft(Gt??0):It.top,il=qt?(qt.x-It.left)/Math.max(1,It.width)>.6:(z?rt.fraction(tl[0]?.value??0):Ft(Gt??0)/Math.max(1,Dt))>.6,sl={...Vt,hovered:Ke.hovered,activeIndex:Gt,marks:Xt,activeMark:qt},rl=0===Ge||null===et||"value"===G&&null===ot,ol=chartTableName({label:he,"aria-label":me,"aria-labelledby":pe});return l(ChartSurface,{...Ne,size:Ce,variant:be,padded:ke,className:we,legendSide:Fe,legend:Ee?e(ChartLegendBar,{series:n,colors:Ye,options:De,visibility:Ke,size:Ce,swatch:ne,dashed:ie?qe:void 0,values:De.showValue&&null!==Gt?n.map((e,t)=>{const l=Xe[t]?.[Gt]?.value;return null==l?void 0:Ue(l)}):void 0}):null,table:rl?null:te?.(We,ol)??e(Q,{id:We,...ol,corner:it?.label,categories:Je,series:n,values:Xe,format:Ue,locale:Se}),children:[l("div",{ref:Ae,role:"img",tabIndex:rl?void 0:0,"aria-labelledby":pe,"aria-label":me??he??Te.chart,"aria-describedby":V(fe,rl?Ie:_e),onPointerMove:e=>{if("none"===Ot)return;const t=((e,t)=>{const l=Ae.current;if(!l)return null;const a=l.getBoundingClientRect(),n=`${a.width} ${a.height} ${$e} ${Pe}`;let i=Be.current;return i.key!==n&&(i={key:n,across:L(l,!0).perPixel,down:L(l,!1).perPixel},Be.current=i),{x:(e-a.left)*i.across,y:(t-a.top)*i.down}})(e.clientX,e.clientY);if(Ut){const e=t?((e,t)=>{if(0===Xt.length)return null;let l=null,a=1/0,n=1/0;return Xt.forEach((i,s)=>{const r=Math.hypot(i.x-e,i.y-t),o=void 0===i.rx?Math.max(0,r-i.r):Math.hypot(Math.max(0,Math.abs(i.x-e)-i.rx),Math.max(0,Math.abs(i.y-t)-(i.ry??i.rx)));o<=ee&&(o<a||o===a&&r<n)&&(a=o,n=r,l=s)}),l})(t.x,t.y):null;Ve(null===e?null:markKey(Xt[e],Ke.keys))}else Le(t?((e,t)=>{if(0===Ge)return null;const l=z?t-It.top:e-It.left;if(l<-Et.step||l>Dt+Et.step)return null;const a=Z?Ge<=1?0:Math.round(l/Dt*(Ge-1)):Math.floor(l/Et.step);return Math.min(Ge-1,Math.max(0,a))})(t.x,t.y):null);var l,a;"item"!==Ot||Ut||Oe(t?(l=t.x,a=t.y,z?l:a):null)},onPointerLeave:clearActive,onKeyDown:"none"===Ot?void 0:e=>{const t=z?"ArrowDown":"ArrowRight",l=z?"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(Jt-1);else{if("Escape"!==e.key||null===He&&null===Re)return;clearActive(),e.stopPropagation()}e.preventDefault()},onBlur:clearActive,className:V("relative w-full","rounded-(--plass-radius-xs)","focus-visible:[outline:2px_solid_var(--p-ring)] focus-visible:outline-offset-2",je&&"overflow-hidden"),style:{height:lt??oe},children:[rl?e("div",{id:Ie,className:V("flex h-full items-center justify-center text-(--plass-muted-fg)",U[Ce]),children:ve??Te.empty}):$e>0&&(null!==lt||bt>0)?l("svg",{width:$e,height:bt||"100%",viewBox:`0 0 ${$e} ${bt}`,"aria-hidden":"true",className:"block overflow-visible",children:[e(ChartAxes,{plot:It,scale:rt,band:Et,horizontal:z,inset:Z,categoryPx:Ft,valuePx:Kt,tickTexts:ht,categoryTexts:St,categoryScale:ct,categoryValuePx:Lt,valueAxis:nt,categoryAxis:it,references:st,fontSize:at,zeroPx:Rt,tickAngle:zt?Nt:0,tickBand:zt?8+$(At,Nt,at):at+6}),null===Gt||Ut||"index"!==Ot||!1===Zt.crosshair?null:(()=>{const t=Ft(Gt);return e("line",z?{x1:It.left,x2:It.left+It.width,y1:It.top+t,y2:It.top+t,stroke:"var(--plass-chart-baseline)",strokeWidth:1}:{x1:It.left+t,x2:It.left+t,y1:It.top,y2:It.top+It.height,stroke:"var(--plass-chart-baseline)",strokeWidth:1})})(),Me(sl)]}):null,null!==Gt&&tl.length>0&&"none"!==Ot?Zt.render?e("div",{className:"pointer-events-none absolute z-10",style:il?{right:`calc(100% - ${al}px + 10px)`,top:nl}:{left:al+10,top:nl},children:Zt.render({index:el?.index??Gt,category:el?.category??ll??Je[Gt],items:el?.renderItems??tl})}):e(ChartTooltipPanel,{heading:el?el.heading:f(ll??Je[Gt],Se),items:tl,x:al,y:nl,flip:il,size:Ce}):null]}),rl?null:l("span",{id:_e,className:X,children:[tt.map((e,n)=>l(a.Fragment,{children:[n>0?", ":null,null===e.said?e.name:l(t,{children:[e.name," ",e.said]})]},n)),st.map((e,t)=>l(a.Fragment,{children:[", ",e.label?`${e.label} ${Ue(e.value)}`:Ue(e.value)]},`reference-${t}`))]}),"none"===Ot?null:e(ChartStatus,{heading:null===Gt?void 0:el?.heading??f(ll??Je[Gt],Se),items:tl})]})}function ChartAxes({plot:a,scale:n,horizontal:i,categoryPx:s,valuePx:r,tickTexts:o,categoryTexts:d,categoryScale:c,categoryValuePx:u,valueAxis:h,categoryAxis:m,references:f,fontSize:x,zeroPx:v,tickAngle:y,tickBand:b}){const k=!1!==h?.grid&&!h?.hidden,M=!m?.hidden&&(m?.grid??null!==c),categoryAlong=e=>c?u(c.ticks[e]):(i?a.top:a.left)+s(e),N=Math.max(...d.map(e=>C(e,x)),1),S=y?P(y,x):N+12,$=A(d.length,i?a.height:a.width,i?1.8*x:S),j=A(n.ticks.length,i?a.width:a.height,i?Math.max(...o.map(e=>C(e,x)),1)+16:2*x),B=d.length>1?Math.abs(categoryAlong(1)-categoryAlong(0)):a.width,T=n.ticks.length>1?Math.abs(r(n.ticks[1])-r(n.ticks[0])):a.height,W=d[d.length-1]??"",_=0!==y||p(d.length,$,B,i?1.8*x:C(W,x)),I=p(n.ticks.length,j,T,i?C(o[o.length-1]??"",x):1.6*x);return l("g",{children:[n.ticks.map((t,s)=>{const d=r(t),c=Math.abs(t)<1e-9;return l("g",{children:[k?e("line",i?{x1:d,x2:d,y1:a.top,y2:a.top+a.height,stroke:c?"var(--plass-chart-baseline)":"var(--plass-chart-grid)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:d,y2:d,stroke:c?"var(--plass-chart-baseline)":"var(--plass-chart-grid)",strokeWidth:1}):null,h?.hidden||!z(s,n.ticks.length,j,I)?null:e("text",i?{x:d,y:a.top+a.height+x+6,textAnchor:0===s?"start":s===n.ticks.length-1?"end":"middle",fontSize:x,fill:"var(--plass-muted-fg)",className:"tabular-nums",children:o[s]}:{x:a.left-8,y:d,textAnchor:"end",dominantBaseline:"central",fontSize:x,fill:"var(--plass-muted-fg)",className:"tabular-nums",children:o[s]})]},t)}),m?.hidden?null:l(t,{children:[e("line",i?{x1:v,x2:v,y1:a.top,y2:a.top+a.height,stroke:"var(--plass-chart-axis)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:v,y2:v,stroke:"var(--plass-chart-axis)",strokeWidth:1}),d.map((t,n)=>{const s=categoryAlong(n),r=z(n,d.length,$,_);if(!r&&(i||!M))return null;const o=s,u=a.top+a.height+8+x/2;return i?e("text",{x:a.left-8,y:s,textAnchor:"end",dominantBaseline:"central",fontSize:x,fill:"var(--plass-muted-fg)",className:c?"tabular-nums":void 0,children:t},n):l("g",{children:[M?e("line",{x1:s,x2:s,y1:a.top,y2:a.top+a.height,stroke:"var(--plass-chart-grid)",strokeWidth:1}):null,r?e("text",y?{x:o,y:u,transform:`rotate(${y} ${o} ${u})`,textAnchor:y<0?"end":"start",dominantBaseline:"central",fontSize:x,fill:"var(--plass-muted-fg)",className:c?"tabular-nums":void 0,children:t}:{x:s,y:a.top+a.height+x+6,textAnchor:c?0===n?"start":n===d.length-1?"end":"middle":"middle",fontSize:x,fill:"var(--plass-muted-fg)",className:c?"tabular-nums":void 0,children:t}):null]},n)})]}),f.map((t,n)=>{const s=r(t.value),o=t.color?w(t.color):"var(--plass-muted-fg)",d=!1===t.dashed?void 0:g;return l("g",{children:[e("line",i?{x1:s,x2:s,y1:a.top,y2:a.top+a.height,stroke:o,strokeWidth:1,strokeDasharray:d}:{x1:a.left,x2:a.left+a.width,y1:s,y2:s,stroke:o,strokeWidth:1,strokeDasharray:d}),t.label?e("text",{x:i?s:a.left+a.width,y:i?a.top+x:s-4,textAnchor:i?"middle":"end",fontSize:x,fontWeight:500,fill:o,children:t.label}):null]},n)}),h?.label?e("text",{x:i?a.left+a.width:a.left,y:i?a.top+a.height+b+x+6:a.top-8,textAnchor:i?"end":"start",fontSize:x,fill:"var(--plass-muted-fg)",fontWeight:500,children:h.label}):null,m?.label&&!i?e("text",{x:a.left+a.width,y:a.top+a.height+b+x+6,textAnchor:"end",fontSize:x,fill:"var(--plass-muted-fg)",fontWeight:500,children:m.label}):null]})}export{Q as ChartDataTable,ChartLegendBar,ChartScaleLegend,ChartStatus,ChartSurface,ChartTooltipPanel,chartTableName,entryKeys,givenHeight,useMeasuredSize,useVisibility};
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import * as React from 'react';
16
16
  import type { CartesianContext } from './chart-frame.js';
17
- import type { PlassChartCurve, PlassChartValueLabels } from '../types.js';
17
+ import type { PlassChartCurve, PlassChartLabelColor, PlassChartNulls, PlassChartValueLabels } from '../types.js';
18
18
  /** Whether a point gets a dot on it. */
19
19
  export type ChartMarkers = 'none' | 'auto' | 'all';
20
20
  export interface LineSeriesProps {
@@ -26,12 +26,17 @@ export interface LineSeriesProps {
26
26
  stacked: boolean;
27
27
  markers: ChartMarkers;
28
28
  valueLabels: PlassChartValueLabels;
29
+ /** What colour those labels are written in. */
30
+ valueLabelColor: PlassChartLabelColor;
29
31
  /**
30
- * Bridges a gap instead of breaking at it. Off by default, and it should
31
- * stay off unless the caller knows the gap is an artefact of collection
32
- * rather than a month where nothing happened.
32
+ * What a gap does to the line.
33
+ *
34
+ * Only `connect` reaches this far. `gap` is what the path builder does when
35
+ * it is handed the `null`s, and `zero` was settled before the frame was ever
36
+ * given the data — see `zeroNulls`, which is why a zeroed gap moves the axis
37
+ * and fills the table row as well as the line.
33
38
  */
34
- connectNulls: boolean;
39
+ nulls: PlassChartNulls;
35
40
  /**
36
41
  * Fades the line from a paler step of its own hue at the old end to the full
37
42
  * colour at the new one. One hue throughout — a stroke that changes hue along
@@ -41,4 +46,4 @@ export interface LineSeriesProps {
41
46
  /** Unique per chart instance, so two charts' gradient defs cannot collide. */
42
47
  idPrefix: string;
43
48
  }
44
- export declare function LineSeries({ context, curve, filled, stacked, markers, valueLabels, connectNulls, gradient, idPrefix }: LineSeriesProps): React.JSX.Element;
49
+ export declare function LineSeries({ context, curve, filled, stacked, markers, valueLabels, valueLabelColor, nulls, gradient, idPrefix }: LineSeriesProps): React.JSX.Element;
@@ -1 +1 @@
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)})]})}
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as r from"react";import{areaPath as l,chartFontSizes as a,dimmedByHover as o,labelledPoints as n,linePath as s,lineDash as i,lineWidths as c,markerRadii as u,markGap as m}from"./chart.js";import{markTransitionClasses as p}from"./chart-frame.js";import{usePrefersReducedMotion as d}from"./media.js";export function LineSeries({context:f,curve:h,filled:x,stacked:k,markers:y,valueLabels:g,valueLabelColor:v,nulls:$,gradient:b,idPrefix:S}){const{values:j,visible:w,colors:N,dashed:C,hovered:L,activeIndex:W,plot:z,point:B,zeroPx:E,size:G,format:M}=f,O=c[G],P=u[G],T=w.indexOf(!0),U=[],A=[];j.forEach((e,t)=>{const r=e.map((e,t)=>A[t]??0);U.push(r),k&&w[t]&&e.forEach((e,t)=>{A[t]=(A[t]??0)+(e.value??0)})});const D=d(),I=j.map((e,t)=>o(L,t,w)),[q,F]=r.useState(()=>new Set),[H,J]=r.useState(I);(I.length!==H.length||I.some((e,t)=>e!==H[t]))&&(J(I),F(e=>new Set(I.flatMap((t,r)=>t||D||!w[r]||!0!==H[r]&&!e.has(r)?[]:[r]))));const K=j.map((e,t)=>{if(!w[t])return null;const r=e.map((e,r)=>{if(null===e.value)return null;const l=k?U[t][r]+e.value:e.value;return B(r,l)}),l=r.flatMap((t,r)=>t&&("all"===y||"auto"===y&&e.length<=14||r===W)?[{...t,category:r,r:r===W?P+1:P}]:[]);return{color:N[t],dimmed:I[t],tops:r,marks:l,cut:(I[t]||q.has(t))&&l.length>0}});return t("g",{children:[t("defs",{children:[b?N.map((r,l)=>t("linearGradient",{id:`${S}-stroke-${l}`,x1:"0",y1:"0",x2:"1",y2:"0",children:[e("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 45%, transparent)`}),e("stop",{offset:"100%",stopColor:r})]},`stroke-${l}`)):null,x&&!k?N.map((r,l)=>t("linearGradient",{id:`${S}-fill-${l}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[e("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 28%, transparent)`}),e("stop",{offset:"100%",stopColor:`color-mix(in oklab, ${r} 2%, transparent)`})]},`fill-${l}`)):null,K.map((r,l)=>r?.cut?t("mask",{id:`${S}-cut-${l}`,maskUnits:"userSpaceOnUse",x:"-50%",y:"-50%",width:"200%",height:"200%",children:[e("rect",{x:"-50%",y:"-50%",width:"200%",height:"200%",fill:"white"}),r.marks.map(t=>e("circle",{cx:t.x,cy:t.y,r:t.r+m/2,fill:"black",className:p},t.category))]},`cut-${l}`):null)]}),j.map((r,a)=>{const o=K[a];if(!o)return null;const{color:n,tops:c}=o,u="connect"===$,d=u?c.filter(Boolean):c,f=r.map((e,t)=>null===e.value?null:k?B(t,U[a][t]):{x:B(t,e.value).x,y:E}),y=x&&k;return t("g",{opacity:o.dimmed?.28:1,mask:o.cut?`url(#${S}-cut-${a})`:void 0,className:p,onTransitionEnd:q.has(a)?e=>{e.target===e.currentTarget&&"opacity"===e.propertyName&&F(e=>new Set([...e].filter(e=>e!==a)))}:void 0,children:[x?e("path",{d:l(d,u?f.filter(Boolean):f,h),fill:k?`color-mix(in oklab, ${n} 70%, transparent)`:`url(#${S}-fill-${a})`,stroke:"none"}):null,y&&a!==T?e("path",{d:s(u?f.filter(Boolean):f,h),fill:"none",stroke:"var(--plass-chart-gap)",strokeWidth:m}):null,y?null:e("path",{d:s(d,h),fill:"none",stroke:b?`url(#${S}-stroke-${a})`:n,strokeWidth:O,strokeDasharray:C[a]?i:void 0,strokeLinecap:"round",strokeLinejoin:"round"})]},a)}),K.map((t,r)=>t&&t.marks.length>0?e("g",{opacity:t.dimmed?.28:1,className:p,children:t.marks.map(l=>e("circle",{cx:l.x,cy:l.y,r:l.r,fill:j[r][l.category].color??t.color,stroke:"var(--plass-chart-gap)",strokeWidth:m,className:p},l.category))},r):null),"none"===g?null:K.map((t,r)=>{if(!t)return null;const l=j[r],o=n(l,g);return e("g",{opacity:t.dimmed?.28:1,className:p,children:t.tops.map((r,n)=>{const s=l[n].value;return r&&null!==s&&o(n)?e("text",{x:r.x,y:r.y-P-5,textAnchor:r.x>z.left+z.width-24?"end":r.x<z.left+24?"start":"middle",fontSize:a[G],fontWeight:600,fill:"ink"===v?"var(--plass-fg)":l[n].color??t.color,className:"tabular-nums",children:l[n].label??M(s)},n):null})},r)})]})}