@nastechai-research/ui 0.18.2

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 (352) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +21 -0
  3. package/dist/assets/filler-bg0.webp +0 -0
  4. package/dist/assets.d.ts +38 -0
  5. package/dist/fonts/Collapse-Bold.woff2 +0 -0
  6. package/dist/fonts/Collapse-BoldItalic.woff2 +0 -0
  7. package/dist/fonts/Collapse-Italic.woff2 +0 -0
  8. package/dist/fonts/Collapse-Light.woff2 +0 -0
  9. package/dist/fonts/Collapse-LightItalic.woff2 +0 -0
  10. package/dist/fonts/Collapse-Regular.woff2 +0 -0
  11. package/dist/fonts/Collapse-Thin.woff2 +0 -0
  12. package/dist/fonts/Collapse-ThinItalic.woff2 +0 -0
  13. package/dist/fonts/Mondwest-Regular.woff2 +0 -0
  14. package/dist/fonts/Neuebit-Bold.woff2 +0 -0
  15. package/dist/fonts/RulesCompressed-Medium.woff2 +0 -0
  16. package/dist/fonts/RulesCompressed-Regular.woff2 +0 -0
  17. package/dist/fonts/RulesExpanded-Bold.woff2 +0 -0
  18. package/dist/fonts/RulesExpanded-Regular.woff2 +0 -0
  19. package/dist/fonts.d.ts +6 -0
  20. package/dist/fonts.js +6 -0
  21. package/dist/hooks/use-below-breakpoint.d.ts +2 -0
  22. package/dist/hooks/use-below-breakpoint.js +17 -0
  23. package/dist/hooks/use-capped-frame.d.ts +2 -0
  24. package/dist/hooks/use-capped-frame.js +15 -0
  25. package/dist/hooks/use-confirm-delete.d.ts +10 -0
  26. package/dist/hooks/use-confirm-delete.js +35 -0
  27. package/dist/hooks/use-css-var-dims.d.ts +1 -0
  28. package/dist/hooks/use-css-var-dims.js +29 -0
  29. package/dist/hooks/use-gpu-tier.d.ts +34 -0
  30. package/dist/hooks/use-gpu-tier.js +111 -0
  31. package/dist/hooks/use-render-loop.d.ts +41 -0
  32. package/dist/hooks/use-render-loop.js +63 -0
  33. package/dist/hooks/use-smooth-controls.d.ts +16 -0
  34. package/dist/hooks/use-smooth-controls.js +217 -0
  35. package/dist/hooks/use-toast.d.ts +7 -0
  36. package/dist/hooks/use-toast.js +21 -0
  37. package/dist/index.d.ts +79 -0
  38. package/dist/index.js +107 -0
  39. package/dist/ui/basic-page.d.ts +7 -0
  40. package/dist/ui/basic-page.js +18 -0
  41. package/dist/ui/build.css +4 -0
  42. package/dist/ui/components/animated-count.d.ts +10 -0
  43. package/dist/ui/components/animated-count.js +113 -0
  44. package/dist/ui/components/ascii.d.ts +10 -0
  45. package/dist/ui/components/ascii.js +79 -0
  46. package/dist/ui/components/badge.d.ts +6 -0
  47. package/dist/ui/components/badge.js +40 -0
  48. package/dist/ui/components/badges/nous-girl.d.ts +2 -0
  49. package/dist/ui/components/badges/nous-girl.js +83 -0
  50. package/dist/ui/components/blend-mode.d.ts +28 -0
  51. package/dist/ui/components/blend-mode.js +69 -0
  52. package/dist/ui/components/blink.d.ts +6 -0
  53. package/dist/ui/components/blink.js +17 -0
  54. package/dist/ui/components/bottom-sheet.d.ts +15 -0
  55. package/dist/ui/components/bottom-sheet.js +192 -0
  56. package/dist/ui/components/button.d.ts +14 -0
  57. package/dist/ui/components/button.js +147 -0
  58. package/dist/ui/components/card.d.ts +5 -0
  59. package/dist/ui/components/card.js +74 -0
  60. package/dist/ui/components/checkbox.d.ts +2 -0
  61. package/dist/ui/components/checkbox.js +27 -0
  62. package/dist/ui/components/command-block.d.ts +24 -0
  63. package/dist/ui/components/command-block.js +56 -0
  64. package/dist/ui/components/confirm-dialog.d.ts +13 -0
  65. package/dist/ui/components/confirm-dialog.js +113 -0
  66. package/dist/ui/components/cursor.d.ts +3 -0
  67. package/dist/ui/components/cursor.js +97 -0
  68. package/dist/ui/components/dialog.d.ts +15 -0
  69. package/dist/ui/components/dialog.js +171 -0
  70. package/dist/ui/components/dropdown-menu.d.ts +12 -0
  71. package/dist/ui/components/dropdown-menu.js +102 -0
  72. package/dist/ui/components/fit-text/fit-text.css +42 -0
  73. package/dist/ui/components/fit-text/index.d.ts +9 -0
  74. package/dist/ui/components/fit-text/index.js +25 -0
  75. package/dist/ui/components/graphs/bar-chart.d.ts +12 -0
  76. package/dist/ui/components/graphs/bar-chart.js +129 -0
  77. package/dist/ui/components/graphs/index.d.ts +3 -0
  78. package/dist/ui/components/graphs/index.js +4 -0
  79. package/dist/ui/components/graphs/line-chart.d.ts +14 -0
  80. package/dist/ui/components/graphs/line-chart.js +175 -0
  81. package/dist/ui/components/graphs/utils.d.ts +52 -0
  82. package/dist/ui/components/graphs/utils.js +162 -0
  83. package/dist/ui/components/grid/grid.css +79 -0
  84. package/dist/ui/components/grid/index.d.ts +2 -0
  85. package/dist/ui/components/grid/index.js +17 -0
  86. package/dist/ui/components/hover-bg.d.ts +1 -0
  87. package/dist/ui/components/hover-bg.js +14 -0
  88. package/dist/ui/components/icons/arrow.d.ts +6 -0
  89. package/dist/ui/components/icons/arrow.js +44 -0
  90. package/dist/ui/components/icons/check.d.ts +2 -0
  91. package/dist/ui/components/icons/check.js +13 -0
  92. package/dist/ui/components/icons/chevron.d.ts +6 -0
  93. package/dist/ui/components/icons/chevron.js +51 -0
  94. package/dist/ui/components/icons/discord.d.ts +2 -0
  95. package/dist/ui/components/icons/discord.js +15 -0
  96. package/dist/ui/components/icons/eye.d.ts +2 -0
  97. package/dist/ui/components/icons/eye.js +8 -0
  98. package/dist/ui/components/icons/gear.d.ts +6 -0
  99. package/dist/ui/components/icons/gear.js +30 -0
  100. package/dist/ui/components/icons/github.d.ts +2 -0
  101. package/dist/ui/components/icons/github.js +15 -0
  102. package/dist/ui/components/icons/hamburger.d.ts +6 -0
  103. package/dist/ui/components/icons/hamburger.js +56 -0
  104. package/dist/ui/components/icons/heart.d.ts +2 -0
  105. package/dist/ui/components/icons/heart.js +11 -0
  106. package/dist/ui/components/icons/index.d.ts +12 -0
  107. package/dist/ui/components/icons/index.js +13 -0
  108. package/dist/ui/components/icons/link.d.ts +2 -0
  109. package/dist/ui/components/icons/link.js +13 -0
  110. package/dist/ui/components/icons/minus.d.ts +2 -0
  111. package/dist/ui/components/icons/minus.js +13 -0
  112. package/dist/ui/components/icons/search.d.ts +2 -0
  113. package/dist/ui/components/icons/search.js +33 -0
  114. package/dist/ui/components/image-distortion.d.ts +21 -0
  115. package/dist/ui/components/image-distortion.js +398 -0
  116. package/dist/ui/components/input.d.ts +1 -0
  117. package/dist/ui/components/input.js +21 -0
  118. package/dist/ui/components/label.d.ts +1 -0
  119. package/dist/ui/components/label.js +18 -0
  120. package/dist/ui/components/leva-client.d.ts +1 -0
  121. package/dist/ui/components/leva-client.js +12 -0
  122. package/dist/ui/components/list-item.d.ts +6 -0
  123. package/dist/ui/components/list-item.js +27 -0
  124. package/dist/ui/components/overlays/blend-modes.d.ts +1 -0
  125. package/dist/ui/components/overlays/blend-modes.js +14 -0
  126. package/dist/ui/components/overlays/glitch.d.ts +6 -0
  127. package/dist/ui/components/overlays/glitch.js +209 -0
  128. package/dist/ui/components/overlays/greys.d.ts +6 -0
  129. package/dist/ui/components/overlays/greys.js +339 -0
  130. package/dist/ui/components/overlays/index.d.ts +14 -0
  131. package/dist/ui/components/overlays/index.js +34 -0
  132. package/dist/ui/components/overlays/lens-layers.d.ts +14 -0
  133. package/dist/ui/components/overlays/lens-layers.js +95 -0
  134. package/dist/ui/components/overlays/lens.d.ts +44 -0
  135. package/dist/ui/components/overlays/lens.js +60 -0
  136. package/dist/ui/components/overlays/noise.d.ts +6 -0
  137. package/dist/ui/components/overlays/noise.js +136 -0
  138. package/dist/ui/components/overlays/vignette.d.ts +6 -0
  139. package/dist/ui/components/overlays/vignette.js +47 -0
  140. package/dist/ui/components/poster.d.ts +62 -0
  141. package/dist/ui/components/poster.js +256 -0
  142. package/dist/ui/components/progress.d.ts +9 -0
  143. package/dist/ui/components/progress.js +53 -0
  144. package/dist/ui/components/scene-canvas.d.ts +23 -0
  145. package/dist/ui/components/scene-canvas.js +179 -0
  146. package/dist/ui/components/scramble.d.ts +9 -0
  147. package/dist/ui/components/scramble.js +63 -0
  148. package/dist/ui/components/segmented.d.ts +20 -0
  149. package/dist/ui/components/segmented.js +51 -0
  150. package/dist/ui/components/select.d.ts +18 -0
  151. package/dist/ui/components/select.js +215 -0
  152. package/dist/ui/components/selection-switcher.d.ts +1 -0
  153. package/dist/ui/components/selection-switcher.js +34 -0
  154. package/dist/ui/components/separator.d.ts +5 -0
  155. package/dist/ui/components/separator.js +22 -0
  156. package/dist/ui/components/shader.d.ts +7 -0
  157. package/dist/ui/components/shader.js +60 -0
  158. package/dist/ui/components/socials.d.ts +20 -0
  159. package/dist/ui/components/socials.js +21 -0
  160. package/dist/ui/components/spinner.d.ts +20 -0
  161. package/dist/ui/components/spinner.js +38 -0
  162. package/dist/ui/components/stats.d.ts +16 -0
  163. package/dist/ui/components/stats.js +36 -0
  164. package/dist/ui/components/switch.d.ts +7 -0
  165. package/dist/ui/components/switch.js +37 -0
  166. package/dist/ui/components/tabs.d.ts +14 -0
  167. package/dist/ui/components/tabs.js +44 -0
  168. package/dist/ui/components/terminal-demo.d.ts +32 -0
  169. package/dist/ui/components/terminal-demo.js +125 -0
  170. package/dist/ui/components/theme-toggle.d.ts +6 -0
  171. package/dist/ui/components/theme-toggle.js +66 -0
  172. package/dist/ui/components/tier-card.d.ts +53 -0
  173. package/dist/ui/components/tier-card.js +146 -0
  174. package/dist/ui/components/toast.d.ts +8 -0
  175. package/dist/ui/components/toast.js +39 -0
  176. package/dist/ui/components/tv.d.ts +3 -0
  177. package/dist/ui/components/tv.js +239 -0
  178. package/dist/ui/components/typography/h1.d.ts +11 -0
  179. package/dist/ui/components/typography/h1.js +18 -0
  180. package/dist/ui/components/typography/h2.d.ts +11 -0
  181. package/dist/ui/components/typography/h2.js +18 -0
  182. package/dist/ui/components/typography/index.d.ts +15 -0
  183. package/dist/ui/components/typography/index.js +41 -0
  184. package/dist/ui/components/typography/legend.d.ts +6 -0
  185. package/dist/ui/components/typography/legend.js +20 -0
  186. package/dist/ui/components/typography/small.d.ts +2 -0
  187. package/dist/ui/components/typography/small.js +9 -0
  188. package/dist/ui/components/watchlist.d.ts +11 -0
  189. package/dist/ui/components/watchlist.js +80 -0
  190. package/dist/ui/fonts.css +63 -0
  191. package/dist/ui/footer.d.ts +20 -0
  192. package/dist/ui/footer.js +65 -0
  193. package/dist/ui/globals.css +395 -0
  194. package/dist/ui/header.d.ts +41 -0
  195. package/dist/ui/header.js +270 -0
  196. package/dist/ui/layout-wrapper.d.ts +1 -0
  197. package/dist/ui/layout-wrapper.js +7 -0
  198. package/dist/utils/color.d.ts +4 -0
  199. package/dist/utils/color.js +14 -0
  200. package/dist/utils/index.d.ts +15 -0
  201. package/dist/utils/index.js +48 -0
  202. package/dist/utils/poly.d.ts +8 -0
  203. package/dist/utils/poly.js +3 -0
  204. package/package.json +120 -0
  205. package/src/assets/filler-bg0.webp +0 -0
  206. package/src/assets.d.ts +38 -0
  207. package/src/fonts/Collapse-Bold.woff2 +0 -0
  208. package/src/fonts/Collapse-BoldItalic.woff2 +0 -0
  209. package/src/fonts/Collapse-Italic.woff2 +0 -0
  210. package/src/fonts/Collapse-Light.woff2 +0 -0
  211. package/src/fonts/Collapse-LightItalic.woff2 +0 -0
  212. package/src/fonts/Collapse-Regular.woff2 +0 -0
  213. package/src/fonts/Collapse-Thin.woff2 +0 -0
  214. package/src/fonts/Collapse-ThinItalic.woff2 +0 -0
  215. package/src/fonts/Mondwest-Regular.woff2 +0 -0
  216. package/src/fonts/Neuebit-Bold.woff2 +0 -0
  217. package/src/fonts/RulesCompressed-Medium.woff2 +0 -0
  218. package/src/fonts/RulesCompressed-Regular.woff2 +0 -0
  219. package/src/fonts/RulesExpanded-Bold.woff2 +0 -0
  220. package/src/fonts/RulesExpanded-Regular.woff2 +0 -0
  221. package/src/fonts.ts +6 -0
  222. package/src/hooks/use-below-breakpoint.ts +21 -0
  223. package/src/hooks/use-capped-frame.ts +18 -0
  224. package/src/hooks/use-confirm-delete.ts +43 -0
  225. package/src/hooks/use-css-var-dims.ts +39 -0
  226. package/src/hooks/use-gpu-tier.ts +190 -0
  227. package/src/hooks/use-render-loop.ts +121 -0
  228. package/src/hooks/use-smooth-controls.ts +318 -0
  229. package/src/hooks/use-toast.ts +29 -0
  230. package/src/index.ts +130 -0
  231. package/src/ui/basic-page.tsx +34 -0
  232. package/src/ui/build.css +4 -0
  233. package/src/ui/components/animated-count.stories.tsx +67 -0
  234. package/src/ui/components/animated-count.tsx +168 -0
  235. package/src/ui/components/ascii.stories.tsx +30 -0
  236. package/src/ui/components/ascii.tsx +110 -0
  237. package/src/ui/components/badge.stories.tsx +31 -0
  238. package/src/ui/components/badge.tsx +60 -0
  239. package/src/ui/components/badges/nous-girl.tsx +52 -0
  240. package/src/ui/components/blend-mode.stories.tsx +33 -0
  241. package/src/ui/components/blend-mode.tsx +129 -0
  242. package/src/ui/components/blink.stories.tsx +32 -0
  243. package/src/ui/components/blink.tsx +21 -0
  244. package/src/ui/components/bottom-sheet.stories.tsx +43 -0
  245. package/src/ui/components/bottom-sheet.tsx +227 -0
  246. package/src/ui/components/button.stories.tsx +68 -0
  247. package/src/ui/components/button.tsx +170 -0
  248. package/src/ui/components/card.stories.tsx +63 -0
  249. package/src/ui/components/card.tsx +85 -0
  250. package/src/ui/components/checkbox.stories.tsx +113 -0
  251. package/src/ui/components/checkbox.tsx +36 -0
  252. package/src/ui/components/command-block.stories.tsx +52 -0
  253. package/src/ui/components/command-block.tsx +86 -0
  254. package/src/ui/components/confirm-dialog.stories.tsx +91 -0
  255. package/src/ui/components/confirm-dialog.tsx +130 -0
  256. package/src/ui/components/cursor.tsx +115 -0
  257. package/src/ui/components/dialog.stories.tsx +169 -0
  258. package/src/ui/components/dialog.tsx +177 -0
  259. package/src/ui/components/dropdown-menu.stories.tsx +52 -0
  260. package/src/ui/components/dropdown-menu.tsx +117 -0
  261. package/src/ui/components/fit-text/fit-text.css +42 -0
  262. package/src/ui/components/fit-text/index.stories.tsx +33 -0
  263. package/src/ui/components/fit-text/index.tsx +45 -0
  264. package/src/ui/components/forms.stories.tsx +173 -0
  265. package/src/ui/components/graphs/bar-chart.tsx +153 -0
  266. package/src/ui/components/graphs/index.stories.tsx +64 -0
  267. package/src/ui/components/graphs/index.tsx +4 -0
  268. package/src/ui/components/graphs/line-chart.tsx +213 -0
  269. package/src/ui/components/graphs/utils.tsx +265 -0
  270. package/src/ui/components/grid/grid.css +79 -0
  271. package/src/ui/components/grid/index.tsx +19 -0
  272. package/src/ui/components/hover-bg.stories.tsx +29 -0
  273. package/src/ui/components/hover-bg.tsx +15 -0
  274. package/src/ui/components/icons/arrow.tsx +42 -0
  275. package/src/ui/components/icons/check.tsx +14 -0
  276. package/src/ui/components/icons/chevron.tsx +45 -0
  277. package/src/ui/components/icons/discord.tsx +16 -0
  278. package/src/ui/components/icons/eye.tsx +12 -0
  279. package/src/ui/components/icons/gear.tsx +51 -0
  280. package/src/ui/components/icons/github.tsx +16 -0
  281. package/src/ui/components/icons/hamburger.tsx +52 -0
  282. package/src/ui/components/icons/heart.tsx +12 -0
  283. package/src/ui/components/icons/index.ts +12 -0
  284. package/src/ui/components/icons/link.tsx +14 -0
  285. package/src/ui/components/icons/minus.tsx +14 -0
  286. package/src/ui/components/icons/search.tsx +28 -0
  287. package/src/ui/components/image-distortion.stories.tsx +120 -0
  288. package/src/ui/components/image-distortion.tsx +499 -0
  289. package/src/ui/components/input.stories.tsx +39 -0
  290. package/src/ui/components/input.tsx +20 -0
  291. package/src/ui/components/label.stories.tsx +26 -0
  292. package/src/ui/components/label.tsx +16 -0
  293. package/src/ui/components/leva-client.tsx +14 -0
  294. package/src/ui/components/list-item.stories.tsx +83 -0
  295. package/src/ui/components/list-item.tsx +37 -0
  296. package/src/ui/components/overlays/blend-modes.ts +13 -0
  297. package/src/ui/components/overlays/glitch.tsx +243 -0
  298. package/src/ui/components/overlays/greys.tsx +386 -0
  299. package/src/ui/components/overlays/index.tsx +47 -0
  300. package/src/ui/components/overlays/lens-layers.tsx +121 -0
  301. package/src/ui/components/overlays/lens.ts +91 -0
  302. package/src/ui/components/overlays/noise.tsx +174 -0
  303. package/src/ui/components/overlays/vignette.tsx +60 -0
  304. package/src/ui/components/poster.stories.tsx +513 -0
  305. package/src/ui/components/poster.tsx +411 -0
  306. package/src/ui/components/progress.stories.tsx +48 -0
  307. package/src/ui/components/progress.tsx +56 -0
  308. package/src/ui/components/scene-canvas.tsx +254 -0
  309. package/src/ui/components/scramble.stories.tsx +49 -0
  310. package/src/ui/components/scramble.tsx +95 -0
  311. package/src/ui/components/segmented.stories.tsx +101 -0
  312. package/src/ui/components/segmented.tsx +81 -0
  313. package/src/ui/components/select.stories.tsx +88 -0
  314. package/src/ui/components/select.tsx +267 -0
  315. package/src/ui/components/selection-switcher.tsx +44 -0
  316. package/src/ui/components/separator.stories.tsx +33 -0
  317. package/src/ui/components/separator.tsx +24 -0
  318. package/src/ui/components/shader.tsx +83 -0
  319. package/src/ui/components/socials.tsx +42 -0
  320. package/src/ui/components/spinner.stories.tsx +101 -0
  321. package/src/ui/components/spinner.tsx +60 -0
  322. package/src/ui/components/stats.stories.tsx +24 -0
  323. package/src/ui/components/stats.tsx +53 -0
  324. package/src/ui/components/switch.stories.tsx +77 -0
  325. package/src/ui/components/switch.tsx +48 -0
  326. package/src/ui/components/tabs.stories.tsx +101 -0
  327. package/src/ui/components/tabs.tsx +66 -0
  328. package/src/ui/components/terminal-demo.stories.tsx +67 -0
  329. package/src/ui/components/terminal-demo.tsx +189 -0
  330. package/src/ui/components/theme-toggle.stories.tsx +47 -0
  331. package/src/ui/components/theme-toggle.tsx +66 -0
  332. package/src/ui/components/tier-card.stories.tsx +217 -0
  333. package/src/ui/components/tier-card.tsx +190 -0
  334. package/src/ui/components/toast.stories.tsx +55 -0
  335. package/src/ui/components/toast.tsx +49 -0
  336. package/src/ui/components/tv.stories.tsx +37 -0
  337. package/src/ui/components/tv.tsx +257 -0
  338. package/src/ui/components/typography/h1.tsx +18 -0
  339. package/src/ui/components/typography/h2.tsx +18 -0
  340. package/src/ui/components/typography/index.tsx +54 -0
  341. package/src/ui/components/typography/legend.tsx +24 -0
  342. package/src/ui/components/typography/small.tsx +11 -0
  343. package/src/ui/components/watchlist.stories.tsx +33 -0
  344. package/src/ui/components/watchlist.tsx +105 -0
  345. package/src/ui/fonts.css +63 -0
  346. package/src/ui/footer.tsx +111 -0
  347. package/src/ui/globals.css +395 -0
  348. package/src/ui/header.tsx +398 -0
  349. package/src/ui/layout-wrapper.tsx +11 -0
  350. package/src/utils/color.ts +21 -0
  351. package/src/utils/index.ts +62 -0
  352. package/src/utils/poly.ts +26 -0
@@ -0,0 +1,102 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useId, useRef, useState } from "react";
4
+ import { cn } from "../../utils/index.js";
5
+ const font = "font-mondwest text-[.9375rem] leading-[1.4] tracking-[0.1875rem]";
6
+ export function DropdownMenu({
7
+ className,
8
+ direction = "down",
9
+ onChange,
10
+ options,
11
+ value
12
+ }) {
13
+ const id = useId();
14
+ const [open, setOpen] = useState(false);
15
+ const ref = useRef(null);
16
+ const anchor = `--dropdown-${id.replace(/:/g, "")}`;
17
+ const panelStyle = {
18
+ position: "fixed",
19
+ positionAnchor: anchor,
20
+ positionTryFallbacks: direction === "left" || direction === "right" ? "flip-inline, flip-block" : "flip-block, flip-inline",
21
+ ...direction === "up" && {
22
+ left: "calc(anchor(left) - 0.5rem)",
23
+ top: "calc(anchor(top) + 1rem)",
24
+ transform: "translateY(-100%)"
25
+ },
26
+ ...direction === "right" && {
27
+ left: "calc(anchor(right))",
28
+ top: "calc(anchor(top) - 0.5rem)"
29
+ },
30
+ ...direction === "left" && {
31
+ left: "calc(anchor(left) - 1px)",
32
+ top: "calc(anchor(top) - 0.5rem)",
33
+ transform: "translateX(-100%)"
34
+ },
35
+ ...direction === "down" && {
36
+ left: "calc(anchor(left) - 0.5rem)",
37
+ top: "calc(anchor(top) - 0.5rem)"
38
+ }
39
+ };
40
+ useEffect(() => {
41
+ if (!open) {
42
+ return;
43
+ }
44
+ const ac = new AbortController();
45
+ document.addEventListener(
46
+ "mousedown",
47
+ (e) => {
48
+ if (!ref.current?.contains(e.target)) {
49
+ setOpen(false);
50
+ }
51
+ },
52
+ { signal: ac.signal }
53
+ );
54
+ return () => ac.abort();
55
+ }, [open]);
56
+ return /* @__PURE__ */ jsxs(
57
+ "span",
58
+ {
59
+ className: cn("relative inline-block align-top", className),
60
+ ref,
61
+ children: [
62
+ /* @__PURE__ */ jsxs(
63
+ "span",
64
+ {
65
+ className: cn(font, "inline-block cursor-pointer hover:underline"),
66
+ onClick: () => setOpen(!open),
67
+ style: { anchorName: anchor },
68
+ children: [
69
+ options.find((o) => o.value === value)?.label ?? value,
70
+ " ",
71
+ open ? "\u2191" : "\u2193"
72
+ ]
73
+ }
74
+ ),
75
+ open && /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ className: "bg-background-base z-50 flex flex-col",
79
+ style: panelStyle,
80
+ children: options.map((o) => /* @__PURE__ */ jsx(
81
+ "span",
82
+ {
83
+ className: cn(
84
+ font,
85
+ "block cursor-pointer p-2 whitespace-nowrap",
86
+ o.value === value ? "underline" : "hover:bg-midground/10"
87
+ ),
88
+ onClick: () => {
89
+ onChange(o.value);
90
+ setOpen(false);
91
+ },
92
+ children: o.label
93
+ },
94
+ o.value
95
+ ))
96
+ }
97
+ )
98
+ ]
99
+ }
100
+ );
101
+ }
102
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlSWQsIHVzZVJlZiwgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCdcblxuaW1wb3J0IHsgY24gfSBmcm9tICcuLi8uLi91dGlscydcblxuY29uc3QgZm9udCA9ICdmb250LW1vbmR3ZXN0IHRleHQtWy45Mzc1cmVtXSBsZWFkaW5nLVsxLjRdIHRyYWNraW5nLVswLjE4NzVyZW1dJ1xuXG50eXBlIERpcmVjdGlvbiA9ICdkb3duJyB8ICd1cCcgfCAnbGVmdCcgfCAncmlnaHQnXG5cbnR5cGUgQW5jaG9yU3R5bGUgPSBSZWFjdC5DU1NQcm9wZXJ0aWVzICYgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyPlxuXG5leHBvcnQgZnVuY3Rpb24gRHJvcGRvd25NZW51PFQgZXh0ZW5kcyBzdHJpbmc+KHtcbiAgY2xhc3NOYW1lLFxuICBkaXJlY3Rpb24gPSAnZG93bicsXG4gIG9uQ2hhbmdlLFxuICBvcHRpb25zLFxuICB2YWx1ZVxufToge1xuICBjbGFzc05hbWU/OiBzdHJpbmdcbiAgZGlyZWN0aW9uPzogRGlyZWN0aW9uXG4gIG9uQ2hhbmdlOiAodmFsdWU6IFQpID0+IHZvaWRcbiAgb3B0aW9uczogeyBsYWJlbDogc3RyaW5nOyB2YWx1ZTogVCB9W11cbiAgdmFsdWU6IFRcbn0pIHtcbiAgY29uc3QgaWQgPSB1c2VJZCgpXG4gIGNvbnN0IFtvcGVuLCBzZXRPcGVuXSA9IHVzZVN0YXRlKGZhbHNlKVxuICBjb25zdCByZWYgPSB1c2VSZWY8SFRNTFNwYW5FbGVtZW50PihudWxsKVxuXG4gIGNvbnN0IGFuY2hvciA9IGAtLWRyb3Bkb3duLSR7aWQucmVwbGFjZSgvOi9nLCAnJyl9YFxuXG4gIGNvbnN0IHBhbmVsU3R5bGU6IEFuY2hvclN0eWxlID0ge1xuICAgIHBvc2l0aW9uOiAnZml4ZWQnLFxuICAgIHBvc2l0aW9uQW5jaG9yOiBhbmNob3IsXG4gICAgcG9zaXRpb25UcnlGYWxsYmFja3M6XG4gICAgICBkaXJlY3Rpb24gPT09ICdsZWZ0JyB8fCBkaXJlY3Rpb24gPT09ICdyaWdodCdcbiAgICAgICAgPyAnZmxpcC1pbmxpbmUsIGZsaXAtYmxvY2snXG4gICAgICAgIDogJ2ZsaXAtYmxvY2ssIGZsaXAtaW5saW5lJyxcbiAgICAuLi4oZGlyZWN0aW9uID09PSAndXAnICYmIHtcbiAgICAgIGxlZnQ6ICdjYWxjKGFuY2hvcihsZWZ0KSAtIDAuNXJlbSknLFxuICAgICAgdG9wOiAnY2FsYyhhbmNob3IodG9wKSArIDFyZW0pJyxcbiAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTEwMCUpJ1xuICAgIH0pLFxuICAgIC4uLihkaXJlY3Rpb24gPT09ICdyaWdodCcgJiYge1xuICAgICAgbGVmdDogJ2NhbGMoYW5jaG9yKHJpZ2h0KSknLFxuICAgICAgdG9wOiAnY2FsYyhhbmNob3IodG9wKSAtIDAuNXJlbSknXG4gICAgfSksXG4gICAgLi4uKGRpcmVjdGlvbiA9PT0gJ2xlZnQnICYmIHtcbiAgICAgIGxlZnQ6ICdjYWxjKGFuY2hvcihsZWZ0KSAtIDFweCknLFxuICAgICAgdG9wOiAnY2FsYyhhbmNob3IodG9wKSAtIDAuNXJlbSknLFxuICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgtMTAwJSknXG4gICAgfSksXG4gICAgLi4uKGRpcmVjdGlvbiA9PT0gJ2Rvd24nICYmIHtcbiAgICAgIGxlZnQ6ICdjYWxjKGFuY2hvcihsZWZ0KSAtIDAuNXJlbSknLFxuICAgICAgdG9wOiAnY2FsYyhhbmNob3IodG9wKSAtIDAuNXJlbSknXG4gICAgfSlcbiAgfVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBhYyA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAnbW91c2Vkb3duJyxcbiAgICAgIGUgPT4ge1xuICAgICAgICBpZiAoIXJlZi5jdXJyZW50Py5jb250YWlucyhlLnRhcmdldCBhcyBOb2RlKSkge1xuICAgICAgICAgIHNldE9wZW4oZmFsc2UpXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7IHNpZ25hbDogYWMuc2lnbmFsIH1cbiAgICApXG5cbiAgICByZXR1cm4gKCkgPT4gYWMuYWJvcnQoKVxuICB9LCBbb3Blbl0pXG5cbiAgcmV0dXJuIChcbiAgICA8c3BhblxuICAgICAgY2xhc3NOYW1lPXtjbigncmVsYXRpdmUgaW5saW5lLWJsb2NrIGFsaWduLXRvcCcsIGNsYXNzTmFtZSl9XG4gICAgICByZWY9e3JlZn1cbiAgICA+XG4gICAgICA8c3BhblxuICAgICAgICBjbGFzc05hbWU9e2NuKGZvbnQsICdpbmxpbmUtYmxvY2sgY3Vyc29yLXBvaW50ZXIgaG92ZXI6dW5kZXJsaW5lJyl9XG4gICAgICAgIG9uQ2xpY2s9eygpID0+IHNldE9wZW4oIW9wZW4pfVxuICAgICAgICBzdHlsZT17eyBhbmNob3JOYW1lOiBhbmNob3IgfSBhcyBBbmNob3JTdHlsZX1cbiAgICAgID5cbiAgICAgICAge29wdGlvbnMuZmluZChvID0+IG8udmFsdWUgPT09IHZhbHVlKT8ubGFiZWwgPz8gdmFsdWV9eycgJ31cbiAgICAgICAge29wZW4gPyAnXHUyMTkxJyA6ICdcdTIxOTMnfVxuICAgICAgPC9zcGFuPlxuXG4gICAgICB7b3BlbiAmJiAoXG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzc05hbWU9XCJiZy1iYWNrZ3JvdW5kLWJhc2Ugei01MCBmbGV4IGZsZXgtY29sXCJcbiAgICAgICAgICBzdHlsZT17cGFuZWxTdHlsZX1cbiAgICAgICAgPlxuICAgICAgICAgIHtvcHRpb25zLm1hcChvID0+IChcbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgIGNsYXNzTmFtZT17Y24oXG4gICAgICAgICAgICAgICAgZm9udCxcbiAgICAgICAgICAgICAgICAnYmxvY2sgY3Vyc29yLXBvaW50ZXIgcC0yIHdoaXRlc3BhY2Utbm93cmFwJyxcbiAgICAgICAgICAgICAgICBvLnZhbHVlID09PSB2YWx1ZSA/ICd1bmRlcmxpbmUnIDogJ2hvdmVyOmJnLW1pZGdyb3VuZC8xMCdcbiAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAga2V5PXtvLnZhbHVlfVxuICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB7XG4gICAgICAgICAgICAgICAgb25DaGFuZ2Uoby52YWx1ZSlcbiAgICAgICAgICAgICAgICBzZXRPcGVuKGZhbHNlKVxuICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7by5sYWJlbH1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICApfVxuICAgIDwvc3Bhbj5cbiAgKVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQWtGTSxTQWVNLEtBZk47QUFoRk4sU0FBUyxXQUFXLE9BQU8sUUFBUSxnQkFBZ0I7QUFFbkQsU0FBUyxVQUFVO0FBRW5CLE1BQU0sT0FBTztBQU1OLGdCQUFTLGFBQStCO0FBQUEsRUFDN0M7QUFBQSxFQUNBLFlBQVk7QUFBQSxFQUNaO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRixHQU1HO0FBQ0QsUUFBTSxLQUFLLE1BQU07QUFDakIsUUFBTSxDQUFDLE1BQU0sT0FBTyxJQUFJLFNBQVMsS0FBSztBQUN0QyxRQUFNLE1BQU0sT0FBd0IsSUFBSTtBQUV4QyxRQUFNLFNBQVMsY0FBYyxHQUFHLFFBQVEsTUFBTSxFQUFFLENBQUM7QUFFakQsUUFBTSxhQUEwQjtBQUFBLElBQzlCLFVBQVU7QUFBQSxJQUNWLGdCQUFnQjtBQUFBLElBQ2hCLHNCQUNFLGNBQWMsVUFBVSxjQUFjLFVBQ2xDLDRCQUNBO0FBQUEsSUFDTixHQUFJLGNBQWMsUUFBUTtBQUFBLE1BQ3hCLE1BQU07QUFBQSxNQUNOLEtBQUs7QUFBQSxNQUNMLFdBQVc7QUFBQSxJQUNiO0FBQUEsSUFDQSxHQUFJLGNBQWMsV0FBVztBQUFBLE1BQzNCLE1BQU07QUFBQSxNQUNOLEtBQUs7QUFBQSxJQUNQO0FBQUEsSUFDQSxHQUFJLGNBQWMsVUFBVTtBQUFBLE1BQzFCLE1BQU07QUFBQSxNQUNOLEtBQUs7QUFBQSxNQUNMLFdBQVc7QUFBQSxJQUNiO0FBQUEsSUFDQSxHQUFJLGNBQWMsVUFBVTtBQUFBLE1BQzFCLE1BQU07QUFBQSxNQUNOLEtBQUs7QUFBQSxJQUNQO0FBQUEsRUFDRjtBQUVBLFlBQVUsTUFBTTtBQUNkLFFBQUksQ0FBQyxNQUFNO0FBQ1Q7QUFBQSxJQUNGO0FBRUEsVUFBTSxLQUFLLElBQUksZ0JBQWdCO0FBQy9CLGFBQVM7QUFBQSxNQUNQO0FBQUEsTUFDQSxPQUFLO0FBQ0gsWUFBSSxDQUFDLElBQUksU0FBUyxTQUFTLEVBQUUsTUFBYyxHQUFHO0FBQzVDLGtCQUFRLEtBQUs7QUFBQSxRQUNmO0FBQUEsTUFDRjtBQUFBLE1BQ0EsRUFBRSxRQUFRLEdBQUcsT0FBTztBQUFBLElBQ3RCO0FBRUEsV0FBTyxNQUFNLEdBQUcsTUFBTTtBQUFBLEVBQ3hCLEdBQUcsQ0FBQyxJQUFJLENBQUM7QUFFVCxTQUNFO0FBQUEsSUFBQztBQUFBO0FBQUEsTUFDQyxXQUFXLEdBQUcsbUNBQW1DLFNBQVM7QUFBQSxNQUMxRDtBQUFBLE1BRUE7QUFBQTtBQUFBLFVBQUM7QUFBQTtBQUFBLFlBQ0MsV0FBVyxHQUFHLE1BQU0sNkNBQTZDO0FBQUEsWUFDakUsU0FBUyxNQUFNLFFBQVEsQ0FBQyxJQUFJO0FBQUEsWUFDNUIsT0FBTyxFQUFFLFlBQVksT0FBTztBQUFBLFlBRTNCO0FBQUEsc0JBQVEsS0FBSyxPQUFLLEVBQUUsVUFBVSxLQUFLLEdBQUcsU0FBUztBQUFBLGNBQU87QUFBQSxjQUN0RCxPQUFPLFdBQU07QUFBQTtBQUFBO0FBQUEsUUFDaEI7QUFBQSxRQUVDLFFBQ0M7QUFBQSxVQUFDO0FBQUE7QUFBQSxZQUNDLFdBQVU7QUFBQSxZQUNWLE9BQU87QUFBQSxZQUVOLGtCQUFRLElBQUksT0FDWDtBQUFBLGNBQUM7QUFBQTtBQUFBLGdCQUNDLFdBQVc7QUFBQSxrQkFDVDtBQUFBLGtCQUNBO0FBQUEsa0JBQ0EsRUFBRSxVQUFVLFFBQVEsY0FBYztBQUFBLGdCQUNwQztBQUFBLGdCQUVBLFNBQVMsTUFBTTtBQUNiLDJCQUFTLEVBQUUsS0FBSztBQUNoQiwwQkFBUSxLQUFLO0FBQUEsZ0JBQ2Y7QUFBQSxnQkFFQyxZQUFFO0FBQUE7QUFBQSxjQU5FLEVBQUU7QUFBQSxZQU9ULENBQ0Q7QUFBQTtBQUFBLFFBQ0g7QUFBQTtBQUFBO0FBQUEsRUFFSjtBQUVKOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,42 @@
1
+ .fit-text {
2
+ --fit-captured-length: initial;
3
+ --fit-support-sentinel: var(--fit-captured-length, 9999px);
4
+
5
+ display: flex;
6
+ container-type: inline-size;
7
+
8
+ > [aria-hidden] {
9
+ visibility: hidden;
10
+ }
11
+
12
+ > :not([aria-hidden]) {
13
+ flex-grow: 1;
14
+ container-type: inline-size;
15
+
16
+ --fit-captured-length: 100cqi;
17
+ --fit-available-space: var(--fit-captured-length);
18
+
19
+ > * {
20
+ --fit-support-sentinel: inherit;
21
+ --fit-captured-length: 100cqi;
22
+ --fit-ratio: tan(
23
+ atan2(
24
+ var(--fit-available-space),
25
+ var(--fit-available-space) - var(--fit-captured-length)
26
+ )
27
+ );
28
+
29
+ display: block;
30
+ inline-size: var(--fit-available-space);
31
+ font-size: clamp(
32
+ var(--fit-min, 1em),
33
+ 1em * var(--fit-ratio),
34
+ var(--fit-max, infinity * 1px) - var(--fit-support-sentinel)
35
+ );
36
+
37
+ @container (inline-size > 0) {
38
+ white-space: nowrap;
39
+ }
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,9 @@
1
+ import { type PolyProps } from '../../../utils';
2
+ export declare const FitText: import("../../..").PolyComponent<"span", OwnProps>;
3
+ interface OwnProps {
4
+ children: string;
5
+ max?: string;
6
+ min?: string;
7
+ }
8
+ export type FitTextProps<T extends React.ElementType = 'span'> = PolyProps<T, OwnProps>;
9
+ export {};
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { createElement } from "react";
4
+ import { cn, polyRef } from "../../../utils/index.js";
5
+ export const FitText = polyRef(
6
+ ({ as, children, className, max, min = "1em", style: baseStyle, ...rest }, ref) => {
7
+ if (typeof children !== "string") {
8
+ return null;
9
+ }
10
+ const style = {
11
+ "--fit-max": max ?? "infinity * 1px",
12
+ "--fit-min": min,
13
+ ...baseStyle
14
+ };
15
+ return createElement(
16
+ as ?? "span",
17
+ { ...rest, className: cn("fit-text", className), ref, style },
18
+ /* @__PURE__ */ jsxs(Fragment, { children: [
19
+ /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx("span", { children }) }),
20
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children })
21
+ ] })
22
+ );
23
+ }
24
+ );
25
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCB7IGNyZWF0ZUVsZW1lbnQgfSBmcm9tICdyZWFjdCdcblxuaW1wb3J0IHsgY24sIHR5cGUgUG9seVByb3BzLCBwb2x5UmVmIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMnXG5cbmV4cG9ydCBjb25zdCBGaXRUZXh0ID0gcG9seVJlZjwnc3BhbicsIE93blByb3BzPihcbiAgKFxuICAgIHsgYXMsIGNoaWxkcmVuLCBjbGFzc05hbWUsIG1heCwgbWluID0gJzFlbScsIHN0eWxlOiBiYXNlU3R5bGUsIC4uLnJlc3QgfSxcbiAgICByZWZcbiAgKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBjaGlsZHJlbiAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICAnLS1maXQtbWF4JzogbWF4ID8/ICdpbmZpbml0eSAqIDFweCcsXG4gICAgICAnLS1maXQtbWluJzogbWluLFxuICAgICAgLi4uYmFzZVN0eWxlXG4gICAgfSBhcyBSZWFjdC5DU1NQcm9wZXJ0aWVzXG5cbiAgICByZXR1cm4gY3JlYXRlRWxlbWVudChcbiAgICAgIChhcyA/PyAnc3BhbicpIGFzIFJlYWN0LkVsZW1lbnRUeXBlLFxuICAgICAgeyAuLi5yZXN0LCBjbGFzc05hbWU6IGNuKCdmaXQtdGV4dCcsIGNsYXNzTmFtZSksIHJlZiwgc3R5bGUgfSxcbiAgICAgIDw+XG4gICAgICAgIDxzcGFuPlxuICAgICAgICAgIDxzcGFuPntjaGlsZHJlbn08L3NwYW4+XG4gICAgICAgIDwvc3Bhbj5cblxuICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj57Y2hpbGRyZW59PC9zcGFuPlxuICAgICAgPC8+XG4gICAgKVxuICB9XG4pXG5cbmludGVyZmFjZSBPd25Qcm9wcyB7XG4gIGNoaWxkcmVuOiBzdHJpbmdcbiAgbWF4Pzogc3RyaW5nXG4gIG1pbj86IHN0cmluZ1xufVxuXG5leHBvcnQgdHlwZSBGaXRUZXh0UHJvcHM8VCBleHRlbmRzIFJlYWN0LkVsZW1lbnRUeXBlID0gJ3NwYW4nPiA9IFBvbHlQcm9wczxcbiAgVCxcbiAgT3duUHJvcHNcbj5cbiJdLAogICJtYXBwaW5ncyI6ICI7QUF3Qk0sbUJBRUksS0FGSjtBQXRCTixTQUFTLHFCQUFxQjtBQUU5QixTQUFTLElBQW9CLGVBQWU7QUFFckMsYUFBTSxVQUFVO0FBQUEsRUFDckIsQ0FDRSxFQUFFLElBQUksVUFBVSxXQUFXLEtBQUssTUFBTSxPQUFPLE9BQU8sV0FBVyxHQUFHLEtBQUssR0FDdkUsUUFDRztBQUNILFFBQUksT0FBTyxhQUFhLFVBQVU7QUFDaEMsYUFBTztBQUFBLElBQ1Q7QUFFQSxVQUFNLFFBQVE7QUFBQSxNQUNaLGFBQWEsT0FBTztBQUFBLE1BQ3BCLGFBQWE7QUFBQSxNQUNiLEdBQUc7QUFBQSxJQUNMO0FBRUEsV0FBTztBQUFBLE1BQ0osTUFBTTtBQUFBLE1BQ1AsRUFBRSxHQUFHLE1BQU0sV0FBVyxHQUFHLFlBQVksU0FBUyxHQUFHLEtBQUssTUFBTTtBQUFBLE1BQzVELGlDQUNFO0FBQUEsNEJBQUMsVUFDQyw4QkFBQyxVQUFNLFVBQVMsR0FDbEI7QUFBQSxRQUVBLG9CQUFDLFVBQUssZUFBWSxRQUFRLFVBQVM7QUFBQSxTQUNyQztBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,12 @@
1
+ import { type ChartProps, type DataPoint } from './utils';
2
+ export declare const BarChart: {
3
+ (props: Omit<BarChartProps<DataPoint> & {
4
+ backgroundColor?: string;
5
+ color?: string;
6
+ }, keyof import("../blend-mode").BlendColors>): import("react").JSX.Element;
7
+ displayName: string;
8
+ };
9
+ interface BarChartProps<T extends DataPoint> extends ChartProps<T> {
10
+ xDomain?: [number, number];
11
+ }
12
+ export {};
@@ -0,0 +1,129 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as Plot from "@observablehq/plot";
4
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import { cn } from "../../../utils/index.js";
6
+ import {
7
+ accessor,
8
+ CHART_MARGINS,
9
+ CHART_STYLE,
10
+ Crosshair,
11
+ setupCrosshair,
12
+ stylePlot,
13
+ useDims,
14
+ withChartBlend
15
+ } from "./utils.js";
16
+ export const BarChart = withChartBlend(
17
+ ({
18
+ backgroundColor: _,
19
+ className,
20
+ color: fillColor,
21
+ data = [],
22
+ formatTooltip,
23
+ formatX: formatXProp,
24
+ formatY: formatYProp,
25
+ x = "label",
26
+ xDomain,
27
+ xTicks = [0, 5e4, 1e5],
28
+ y = "value",
29
+ yDomain = [0, 10],
30
+ yTicks = [10, 8, 4, 2],
31
+ ...props
32
+ }) => {
33
+ const ref = useRef(null);
34
+ const plotRef = useRef(null);
35
+ const [crosshair, setCrosshair] = useState({ x: null });
36
+ const dims = useDims(ref);
37
+ const formatX = useCallback(
38
+ (v) => formatXProp?.(v) ?? (typeof v === "number" ? v.toLocaleString("en-US") : String(v)),
39
+ [formatXProp]
40
+ );
41
+ const formatY = useCallback(
42
+ (v) => formatYProp?.(v) ?? String(v),
43
+ [formatYProp]
44
+ );
45
+ const getX = useMemo(() => accessor(x), [x]);
46
+ const getY = useMemo(() => accessor(y), [y]);
47
+ useEffect(() => {
48
+ if (!ref.current || !plotRef.current || !data.length || !dims.h || !dims.w) {
49
+ return;
50
+ }
51
+ plotRef.current.innerHTML = "";
52
+ const [xMin, xMax] = [
53
+ xDomain?.[0] ?? 0,
54
+ xDomain?.[1] ?? Math.max(...data.map((d) => getX(d)))
55
+ ];
56
+ const plot = Plot.plot({
57
+ ...CHART_MARGINS,
58
+ height: dims.h,
59
+ marks: [
60
+ Plot.rectY(data, {
61
+ fill: fillColor ?? "currentColor",
62
+ fillOpacity: 0.3,
63
+ interval: (xMax - xMin) / data.length,
64
+ x: getX,
65
+ y: getY
66
+ }),
67
+ Plot.axisX({ tickFormat: formatX, ticks: xTicks })
68
+ ],
69
+ style: CHART_STYLE,
70
+ width: dims.w,
71
+ x: { domain: [xMin, xMax], label: null, type: "linear" },
72
+ y: {
73
+ domain: yDomain,
74
+ grid: true,
75
+ label: null,
76
+ tickFormat: formatY,
77
+ ticks: yTicks
78
+ }
79
+ });
80
+ stylePlot(plot);
81
+ plotRef.current.appendChild(plot);
82
+ const cleanup = setupCrosshair(
83
+ ref.current,
84
+ data,
85
+ (d) => getX(d),
86
+ getY,
87
+ yDomain,
88
+ (d) => formatTooltip?.(d) ?? `${formatX(getX(d))}: ${formatY(getY(d))}`,
89
+ setCrosshair
90
+ );
91
+ return cleanup;
92
+ }, [
93
+ data,
94
+ dims.h,
95
+ dims.w,
96
+ fillColor,
97
+ formatTooltip,
98
+ formatX,
99
+ formatY,
100
+ getX,
101
+ getY,
102
+ xDomain,
103
+ xTicks,
104
+ yDomain,
105
+ yTicks
106
+ ]);
107
+ return /* @__PURE__ */ jsxs(
108
+ "div",
109
+ {
110
+ className: cn("relative aspect-4/1 w-full overflow-clip", className),
111
+ ref,
112
+ ...props,
113
+ children: [
114
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0", ref: plotRef }),
115
+ /* @__PURE__ */ jsx(
116
+ Crosshair,
117
+ {
118
+ color: fillColor,
119
+ containerWidth: dims.w,
120
+ height: dims.h,
121
+ ...crosshair
122
+ }
123
+ )
124
+ ]
125
+ }
126
+ );
127
+ }
128
+ );
129
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCAqIGFzIFBsb3QgZnJvbSAnQG9ic2VydmFibGVocS9wbG90J1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuXG5pbXBvcnQgeyBjbiB9IGZyb20gJy4uLy4uLy4uL3V0aWxzJ1xuXG5pbXBvcnQge1xuICBhY2Nlc3NvcixcbiAgQ0hBUlRfTUFSR0lOUyxcbiAgQ0hBUlRfU1RZTEUsXG4gIHR5cGUgQ2hhcnRQcm9wcyxcbiAgQ3Jvc3NoYWlyLFxuICB0eXBlIENyb3NzaGFpclN0YXRlLFxuICB0eXBlIERhdGFQb2ludCxcbiAgc2V0dXBDcm9zc2hhaXIsXG4gIHN0eWxlUGxvdCxcbiAgdXNlRGltcyxcbiAgd2l0aENoYXJ0QmxlbmRcbn0gZnJvbSAnLi91dGlscydcblxuZXhwb3J0IGNvbnN0IEJhckNoYXJ0ID0gd2l0aENoYXJ0QmxlbmQoXG4gIDxUIGV4dGVuZHMgRGF0YVBvaW50Pih7XG4gICAgYmFja2dyb3VuZENvbG9yOiBfLFxuICAgIGNsYXNzTmFtZSxcbiAgICBjb2xvcjogZmlsbENvbG9yLFxuICAgIGRhdGEgPSBbXSxcbiAgICBmb3JtYXRUb29sdGlwLFxuICAgIGZvcm1hdFg6IGZvcm1hdFhQcm9wLFxuICAgIGZvcm1hdFk6IGZvcm1hdFlQcm9wLFxuICAgIHggPSAnbGFiZWwnIGFzIGtleW9mIFQsXG4gICAgeERvbWFpbixcbiAgICB4VGlja3MgPSBbMCwgNTAwMDAsIDEwMDAwMF0sXG4gICAgeSA9ICd2YWx1ZScgYXMga2V5b2YgVCxcbiAgICB5RG9tYWluID0gWzAsIDEwXSxcbiAgICB5VGlja3MgPSBbMTAsIDgsIDQsIDJdLFxuICAgIC4uLnByb3BzXG4gIH06IEJhckNoYXJ0UHJvcHM8VD4gJiB7IGJhY2tncm91bmRDb2xvcj86IHN0cmluZzsgY29sb3I/OiBzdHJpbmcgfSkgPT4ge1xuICAgIGNvbnN0IHJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbClcbiAgICBjb25zdCBwbG90UmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKVxuICAgIGNvbnN0IFtjcm9zc2hhaXIsIHNldENyb3NzaGFpcl0gPSB1c2VTdGF0ZTxDcm9zc2hhaXJTdGF0ZT4oeyB4OiBudWxsIH0pXG4gICAgY29uc3QgZGltcyA9IHVzZURpbXMocmVmKVxuXG4gICAgY29uc3QgZm9ybWF0WCA9IHVzZUNhbGxiYWNrKFxuICAgICAgKHY6IHVua25vd24pID0+XG4gICAgICAgIGZvcm1hdFhQcm9wPy4odikgPz9cbiAgICAgICAgKHR5cGVvZiB2ID09PSAnbnVtYmVyJyA/IHYudG9Mb2NhbGVTdHJpbmcoJ2VuLVVTJykgOiBTdHJpbmcodikpLFxuICAgICAgW2Zvcm1hdFhQcm9wXVxuICAgIClcblxuICAgIGNvbnN0IGZvcm1hdFkgPSB1c2VDYWxsYmFjayhcbiAgICAgICh2OiBudW1iZXIpID0+IGZvcm1hdFlQcm9wPy4odikgPz8gU3RyaW5nKHYpLFxuICAgICAgW2Zvcm1hdFlQcm9wXVxuICAgIClcblxuICAgIGNvbnN0IGdldFggPSB1c2VNZW1vKCgpID0+IGFjY2Vzc29yPFQsIHVua25vd24+KHgpLCBbeF0pXG4gICAgY29uc3QgZ2V0WSA9IHVzZU1lbW8oKCkgPT4gYWNjZXNzb3I8VCwgbnVtYmVyPih5KSwgW3ldKVxuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIXJlZi5jdXJyZW50IHx8XG4gICAgICAgICFwbG90UmVmLmN1cnJlbnQgfHxcbiAgICAgICAgIWRhdGEubGVuZ3RoIHx8XG4gICAgICAgICFkaW1zLmggfHxcbiAgICAgICAgIWRpbXMud1xuICAgICAgKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBwbG90UmVmLmN1cnJlbnQuaW5uZXJIVE1MID0gJydcblxuICAgICAgY29uc3QgW3hNaW4sIHhNYXhdID0gW1xuICAgICAgICB4RG9tYWluPy5bMF0gPz8gMCxcbiAgICAgICAgeERvbWFpbj8uWzFdID8/IE1hdGgubWF4KC4uLmRhdGEubWFwKGQgPT4gZ2V0WChkKSBhcyBudW1iZXIpKVxuICAgICAgXVxuXG4gICAgICBjb25zdCBwbG90ID0gUGxvdC5wbG90KHtcbiAgICAgICAgLi4uQ0hBUlRfTUFSR0lOUyxcbiAgICAgICAgaGVpZ2h0OiBkaW1zLmgsXG4gICAgICAgIG1hcmtzOiBbXG4gICAgICAgICAgUGxvdC5yZWN0WShkYXRhLCB7XG4gICAgICAgICAgICBmaWxsOiBmaWxsQ29sb3IgPz8gJ2N1cnJlbnRDb2xvcicsXG4gICAgICAgICAgICBmaWxsT3BhY2l0eTogMC4zLFxuICAgICAgICAgICAgaW50ZXJ2YWw6ICh4TWF4IC0geE1pbikgLyBkYXRhLmxlbmd0aCxcbiAgICAgICAgICAgIHg6IGdldFggYXMgKGQ6IFQpID0+IHVua25vd24sXG4gICAgICAgICAgICB5OiBnZXRZXG4gICAgICAgICAgfSksXG4gICAgICAgICAgUGxvdC5heGlzWCh7IHRpY2tGb3JtYXQ6IGZvcm1hdFgsIHRpY2tzOiB4VGlja3MgfSlcbiAgICAgICAgXSxcbiAgICAgICAgc3R5bGU6IENIQVJUX1NUWUxFLFxuICAgICAgICB3aWR0aDogZGltcy53LFxuICAgICAgICB4OiB7IGRvbWFpbjogW3hNaW4sIHhNYXhdLCBsYWJlbDogbnVsbCwgdHlwZTogJ2xpbmVhcicgfSxcbiAgICAgICAgeToge1xuICAgICAgICAgIGRvbWFpbjogeURvbWFpbixcbiAgICAgICAgICBncmlkOiB0cnVlLFxuICAgICAgICAgIGxhYmVsOiBudWxsLFxuICAgICAgICAgIHRpY2tGb3JtYXQ6IGZvcm1hdFksXG4gICAgICAgICAgdGlja3M6IHlUaWNrc1xuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgICBzdHlsZVBsb3QocGxvdCBhcyBIVE1MRWxlbWVudClcbiAgICAgIHBsb3RSZWYuY3VycmVudC5hcHBlbmRDaGlsZChwbG90KVxuXG4gICAgICBjb25zdCBjbGVhbnVwID0gc2V0dXBDcm9zc2hhaXIoXG4gICAgICAgIHJlZi5jdXJyZW50LFxuICAgICAgICBkYXRhLFxuICAgICAgICBkID0+IGdldFgoZCkgYXMgbnVtYmVyLFxuICAgICAgICBnZXRZLFxuICAgICAgICB5RG9tYWluLFxuICAgICAgICBkID0+IGZvcm1hdFRvb2x0aXA/LihkKSA/PyBgJHtmb3JtYXRYKGdldFgoZCkpfTogJHtmb3JtYXRZKGdldFkoZCkpfWAsXG4gICAgICAgIHNldENyb3NzaGFpclxuICAgICAgKVxuXG4gICAgICByZXR1cm4gY2xlYW51cFxuICAgIH0sIFtcbiAgICAgIGRhdGEsXG4gICAgICBkaW1zLmgsXG4gICAgICBkaW1zLncsXG4gICAgICBmaWxsQ29sb3IsXG4gICAgICBmb3JtYXRUb29sdGlwLFxuICAgICAgZm9ybWF0WCxcbiAgICAgIGZvcm1hdFksXG4gICAgICBnZXRYLFxuICAgICAgZ2V0WSxcbiAgICAgIHhEb21haW4sXG4gICAgICB4VGlja3MsXG4gICAgICB5RG9tYWluLFxuICAgICAgeVRpY2tzXG4gICAgXSlcblxuICAgIHJldHVybiAoXG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzTmFtZT17Y24oJ3JlbGF0aXZlIGFzcGVjdC00LzEgdy1mdWxsIG92ZXJmbG93LWNsaXAnLCBjbGFzc05hbWUpfVxuICAgICAgICByZWY9e3JlZn1cbiAgICAgICAgey4uLnByb3BzfVxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFic29sdXRlIGluc2V0LTBcIiByZWY9e3Bsb3RSZWZ9IC8+XG5cbiAgICAgICAgPENyb3NzaGFpclxuICAgICAgICAgIGNvbG9yPXtmaWxsQ29sb3J9XG4gICAgICAgICAgY29udGFpbmVyV2lkdGg9e2RpbXMud31cbiAgICAgICAgICBoZWlnaHQ9e2RpbXMuaH1cbiAgICAgICAgICB7Li4uY3Jvc3NoYWlyfVxuICAgICAgICAvPlxuICAgICAgPC9kaXY+XG4gICAgKVxuICB9XG4pXG5cbmludGVyZmFjZSBCYXJDaGFydFByb3BzPFQgZXh0ZW5kcyBEYXRhUG9pbnQ+IGV4dGVuZHMgQ2hhcnRQcm9wczxUPiB7XG4gIHhEb21haW4/OiBbbnVtYmVyLCBudW1iZXJdXG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBb0lNLFNBS0UsS0FMRjtBQWxJTixZQUFZLFVBQVU7QUFDdEIsU0FBUyxhQUFhLFdBQVcsU0FBUyxRQUFRLGdCQUFnQjtBQUVsRSxTQUFTLFVBQVU7QUFFbkI7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUVBO0FBQUEsRUFHQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFFQSxhQUFNLFdBQVc7QUFBQSxFQUN0QixDQUFzQjtBQUFBLElBQ3BCLGlCQUFpQjtBQUFBLElBQ2pCO0FBQUEsSUFDQSxPQUFPO0FBQUEsSUFDUCxPQUFPLENBQUM7QUFBQSxJQUNSO0FBQUEsSUFDQSxTQUFTO0FBQUEsSUFDVCxTQUFTO0FBQUEsSUFDVCxJQUFJO0FBQUEsSUFDSjtBQUFBLElBQ0EsU0FBUyxDQUFDLEdBQUcsS0FBTyxHQUFNO0FBQUEsSUFDMUIsSUFBSTtBQUFBLElBQ0osVUFBVSxDQUFDLEdBQUcsRUFBRTtBQUFBLElBQ2hCLFNBQVMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQUEsSUFDckIsR0FBRztBQUFBLEVBQ0wsTUFBdUU7QUFDckUsVUFBTSxNQUFNLE9BQXVCLElBQUk7QUFDdkMsVUFBTSxVQUFVLE9BQXVCLElBQUk7QUFDM0MsVUFBTSxDQUFDLFdBQVcsWUFBWSxJQUFJLFNBQXlCLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFDdEUsVUFBTSxPQUFPLFFBQVEsR0FBRztBQUV4QixVQUFNLFVBQVU7QUFBQSxNQUNkLENBQUMsTUFDQyxjQUFjLENBQUMsTUFDZCxPQUFPLE1BQU0sV0FBVyxFQUFFLGVBQWUsT0FBTyxJQUFJLE9BQU8sQ0FBQztBQUFBLE1BQy9ELENBQUMsV0FBVztBQUFBLElB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
@@ -0,0 +1,3 @@
1
+ export { BarChart } from './bar-chart';
2
+ export { LineChart } from './line-chart';
3
+ export * from './utils';
@@ -0,0 +1,4 @@
1
+ export { BarChart } from "./bar-chart.js";
2
+ export { LineChart } from "./line-chart.js";
3
+ export * from "./utils.js";
4
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IHsgQmFyQ2hhcnQgfSBmcm9tICcuL2Jhci1jaGFydCdcbmV4cG9ydCB7IExpbmVDaGFydCB9IGZyb20gJy4vbGluZS1jaGFydCdcblxuZXhwb3J0ICogZnJvbSAnLi91dGlscydcbiJdLAogICJtYXBwaW5ncyI6ICJBQUFBLFNBQVMsZ0JBQWdCO0FBQ3pCLFNBQVMsaUJBQWlCO0FBRTFCLGNBQWM7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,14 @@
1
+ import { type ChartProps, type DataPoint } from './utils';
2
+ export declare const LineChart: {
3
+ (props: Omit<LineChartProps<DataPoint> & {
4
+ backgroundColor?: string;
5
+ color?: string;
6
+ }, keyof import("../blend-mode").BlendColors>): import("react").JSX.Element;
7
+ displayName: string;
8
+ };
9
+ interface LineChartProps<T extends DataPoint> extends ChartProps<T> {
10
+ curve?: 'basis' | 'catmull-rom' | 'linear' | 'natural' | 'step';
11
+ series?: keyof T;
12
+ showArea?: boolean;
13
+ }
14
+ export {};
@@ -0,0 +1,175 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as Plot from "@observablehq/plot";
4
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import { cn } from "../../../utils/index.js";
6
+ import {
7
+ accessor,
8
+ CHART_MARGINS,
9
+ CHART_STYLE,
10
+ Crosshair,
11
+ setupCrosshair,
12
+ stylePlot,
13
+ useDims,
14
+ withChartBlend
15
+ } from "./utils.js";
16
+ export const LineChart = withChartBlend(
17
+ ({
18
+ backgroundColor: _,
19
+ className,
20
+ color: strokeColor,
21
+ curve = "natural",
22
+ data = [],
23
+ formatTooltip,
24
+ formatX: formatXProp,
25
+ formatY: formatYProp,
26
+ series = "series",
27
+ showArea = false,
28
+ x = "label",
29
+ xTicks,
30
+ y = "value",
31
+ yDomain = [0, 0.5],
32
+ yTicks = 4,
33
+ ...props
34
+ }) => {
35
+ const ref = useRef(null);
36
+ const plotRef = useRef(null);
37
+ const [hovered, setHovered] = useState(null);
38
+ const [crosshair, setCrosshair] = useState({ x: null });
39
+ const dims = useDims(ref);
40
+ const formatX = useCallback(
41
+ (v) => formatXProp?.(v) ?? (v >= 1e3 ? `${v / 1e3}k` : `${v}`),
42
+ [formatXProp]
43
+ );
44
+ const formatY = useCallback(
45
+ (v) => formatYProp?.(v) ?? `${Math.round(v * 100)}%`,
46
+ [formatYProp]
47
+ );
48
+ const getX = useMemo(() => accessor(x), [x]);
49
+ const getY = useMemo(() => accessor(y), [y]);
50
+ const getZ = useCallback((d) => d[series], [series]);
51
+ useEffect(() => {
52
+ if (!ref.current || !plotRef.current || !data.length || !dims.h || !dims.w) {
53
+ return;
54
+ }
55
+ plotRef.current.innerHTML = "";
56
+ const hasSeries = data.some((d) => d[series] !== void 0);
57
+ const seriesIdx = hasSeries ? data.reduce(
58
+ (acc, d, i) => (acc[d[series]] ??= i, acc),
59
+ {}
60
+ ) : {};
61
+ const n = Object.keys(seriesIdx).length;
62
+ const opacity = (d) => {
63
+ if (!hasSeries) {
64
+ return 1;
65
+ }
66
+ if (hovered) {
67
+ return d[series] === hovered[series] ? 1 : 0.2;
68
+ }
69
+ return 1 - seriesIdx[d[series]] / Math.max(n - 1, 1) * 0.2;
70
+ };
71
+ const lineOpts = {
72
+ curve,
73
+ x: getX,
74
+ y: getY,
75
+ ...hasSeries && { z: getZ }
76
+ };
77
+ const plot = Plot.plot({
78
+ ...CHART_MARGINS,
79
+ height: dims.h,
80
+ marks: [
81
+ ...showArea ? [
82
+ Plot.areaY(data, {
83
+ ...lineOpts,
84
+ fill: strokeColor,
85
+ fillOpacity: 0.15,
86
+ y1: yDomain[0]
87
+ })
88
+ ] : [],
89
+ Plot.lineY(data, {
90
+ ...lineOpts,
91
+ stroke: "transparent",
92
+ strokeWidth: 16
93
+ }),
94
+ Plot.lineY(data, {
95
+ ...lineOpts,
96
+ stroke: strokeColor,
97
+ strokeOpacity: opacity,
98
+ strokeWidth: 1.5
99
+ })
100
+ ],
101
+ style: { ...CHART_STYLE, fontStretch: "expanded" },
102
+ width: dims.w,
103
+ x: { label: null, tickFormat: formatX, ticks: xTicks },
104
+ y: {
105
+ domain: yDomain,
106
+ grid: true,
107
+ label: null,
108
+ tickFormat: formatY,
109
+ ticks: yTicks
110
+ }
111
+ });
112
+ plot.addEventListener("input", () => setHovered(plot.value));
113
+ stylePlot(plot);
114
+ plot.querySelectorAll('g[aria-label="line"] path').forEach(
115
+ (el) => Object.assign(el.style, {
116
+ transition: "stroke-opacity 0.2s"
117
+ })
118
+ );
119
+ plotRef.current.appendChild(plot);
120
+ const cleanup = setupCrosshair(
121
+ ref.current,
122
+ data,
123
+ (d) => getX(d),
124
+ getY,
125
+ yDomain,
126
+ (d) => formatTooltip?.(d) ?? `${formatX(getX(d))}: ${formatY(getY(d))}`,
127
+ setCrosshair,
128
+ hasSeries ? (d) => getZ(d) : void 0
129
+ );
130
+ return () => {
131
+ cleanup();
132
+ plot.parentNode && plot.remove();
133
+ };
134
+ }, [
135
+ curve,
136
+ data,
137
+ dims.h,
138
+ dims.w,
139
+ formatTooltip,
140
+ formatX,
141
+ formatY,
142
+ getX,
143
+ getY,
144
+ getZ,
145
+ hovered,
146
+ series,
147
+ showArea,
148
+ strokeColor,
149
+ xTicks,
150
+ yDomain,
151
+ yTicks
152
+ ]);
153
+ return /* @__PURE__ */ jsxs(
154
+ "div",
155
+ {
156
+ className: cn("relative aspect-4/1 w-full overflow-clip", className),
157
+ ref,
158
+ ...props,
159
+ children: [
160
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0", ref: plotRef }),
161
+ /* @__PURE__ */ jsx(
162
+ Crosshair,
163
+ {
164
+ color: strokeColor,
165
+ containerWidth: dims.w,
166
+ height: dims.h,
167
+ ...crosshair
168
+ }
169
+ )
170
+ ]
171
+ }
172
+ );
173
+ }
174
+ );
175
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiPHN0ZGluPiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiJ3VzZSBjbGllbnQnXG5cbmltcG9ydCAqIGFzIFBsb3QgZnJvbSAnQG9ic2VydmFibGVocS9wbG90J1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuXG5pbXBvcnQgeyBjbiB9IGZyb20gJy4uLy4uLy4uL3V0aWxzJ1xuXG5pbXBvcnQge1xuICBhY2Nlc3NvcixcbiAgQ0hBUlRfTUFSR0lOUyxcbiAgQ0hBUlRfU1RZTEUsXG4gIHR5cGUgQ2hhcnRQcm9wcyxcbiAgQ3Jvc3NoYWlyLFxuICB0eXBlIENyb3NzaGFpclN0YXRlLFxuICB0eXBlIERhdGFQb2ludCxcbiAgc2V0dXBDcm9zc2hhaXIsXG4gIHN0eWxlUGxvdCxcbiAgdXNlRGltcyxcbiAgd2l0aENoYXJ0QmxlbmRcbn0gZnJvbSAnLi91dGlscydcblxuZXhwb3J0IGNvbnN0IExpbmVDaGFydCA9IHdpdGhDaGFydEJsZW5kKFxuICA8VCBleHRlbmRzIERhdGFQb2ludD4oe1xuICAgIGJhY2tncm91bmRDb2xvcjogXyxcbiAgICBjbGFzc05hbWUsXG4gICAgY29sb3I6IHN0cm9rZUNvbG9yLFxuICAgIGN1cnZlID0gJ25hdHVyYWwnLFxuICAgIGRhdGEgPSBbXSxcbiAgICBmb3JtYXRUb29sdGlwLFxuICAgIGZvcm1hdFg6IGZvcm1hdFhQcm9wLFxuICAgIGZvcm1hdFk6IGZvcm1hdFlQcm9wLFxuICAgIHNlcmllcyA9ICdzZXJpZXMnIGFzIGtleW9mIFQsXG4gICAgc2hvd0FyZWEgPSBmYWxzZSxcbiAgICB4ID0gJ2xhYmVsJyBhcyBrZXlvZiBULFxuICAgIHhUaWNrcyxcbiAgICB5ID0gJ3ZhbHVlJyBhcyBrZXlvZiBULFxuICAgIHlEb21haW4gPSBbMCwgMC41XSxcbiAgICB5VGlja3MgPSA0LFxuICAgIC4uLnByb3BzXG4gIH06IExpbmVDaGFydFByb3BzPFQ+ICYgeyBiYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmc7IGNvbG9yPzogc3RyaW5nIH0pID0+IHtcbiAgICBjb25zdCByZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQ+KG51bGwpXG4gICAgY29uc3QgcGxvdFJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbClcbiAgICBjb25zdCBbaG92ZXJlZCwgc2V0SG92ZXJlZF0gPSB1c2VTdGF0ZTxudWxsIHwgVD4obnVsbClcbiAgICBjb25zdCBbY3Jvc3NoYWlyLCBzZXRDcm9zc2hhaXJdID0gdXNlU3RhdGU8Q3Jvc3NoYWlyU3RhdGU+KHsgeDogbnVsbCB9KVxuICAgIGNvbnN0IGRpbXMgPSB1c2VEaW1zKHJlZilcblxuICAgIGNvbnN0IGZvcm1hdFggPSB1c2VDYWxsYmFjayhcbiAgICAgICh2OiB1bmtub3duKSA9PlxuICAgICAgICBmb3JtYXRYUHJvcD8uKHYpID8/XG4gICAgICAgICgodiBhcyBudW1iZXIpID49IDFlMyA/IGAkeyh2IGFzIG51bWJlcikgLyAxZTN9a2AgOiBgJHt2fWApLFxuICAgICAgW2Zvcm1hdFhQcm9wXVxuICAgIClcblxuICAgIGNvbnN0IGZvcm1hdFkgPSB1c2VDYWxsYmFjayhcbiAgICAgICh2OiBudW1iZXIpID0+IGZvcm1hdFlQcm9wPy4odikgPz8gYCR7TWF0aC5yb3VuZCh2ICogMTAwKX0lYCxcbiAgICAgIFtmb3JtYXRZUHJvcF1cbiAgICApXG5cbiAgICBjb25zdCBnZXRYID0gdXNlTWVtbygoKSA9PiBhY2Nlc3NvcjxULCB1bmtub3duPih4KSwgW3hdKVxuICAgIGNvbnN0IGdldFkgPSB1c2VNZW1vKCgpID0+IGFjY2Vzc29yPFQsIG51bWJlcj4oeSksIFt5XSlcbiAgICBjb25zdCBnZXRaID0gdXNlQ2FsbGJhY2soKGQ6IFQpID0+IGRbc2VyaWVzXSwgW3Nlcmllc10pXG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICAhcmVmLmN1cnJlbnQgfHxcbiAgICAgICAgIXBsb3RSZWYuY3VycmVudCB8fFxuICAgICAgICAhZGF0YS5sZW5ndGggfHxcbiAgICAgICAgIWRpbXMuaCB8fFxuICAgICAgICAhZGltcy53XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHBsb3RSZWYuY3VycmVudC5pbm5lckhUTUwgPSAnJ1xuXG4gICAgICBjb25zdCBoYXNTZXJpZXMgPSBkYXRhLnNvbWUoZCA9PiBkW3Nlcmllc10gIT09IHVuZGVmaW5lZClcblxuICAgICAgY29uc3Qgc2VyaWVzSWR4ID0gaGFzU2VyaWVzXG4gICAgICAgID8gZGF0YS5yZWR1Y2UoXG4gICAgICAgICAgICAoYWNjLCBkLCBpKSA9PiAoKGFjY1tkW3Nlcmllc10gYXMgc3RyaW5nXSA/Pz0gaSksIGFjYyksXG4gICAgICAgICAgICB7fSBhcyBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+XG4gICAgICAgICAgKVxuICAgICAgICA6IHt9XG5cbiAgICAgIGNvbnN0IG4gPSBPYmplY3Qua2V5cyhzZXJpZXNJZHgpLmxlbmd0aFxuXG4gICAgICBjb25zdCBvcGFjaXR5ID0gKGQ6IFQpID0+IHtcbiAgICAgICAgaWYgKCFoYXNTZXJpZXMpIHtcbiAgICAgICAgICByZXR1cm4gMVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhvdmVyZWQpIHtcbiAgICAgICAgICByZXR1cm4gZFtzZXJpZXNdID09PSBob3ZlcmVkW3Nlcmllc10gPyAxIDogMC4yXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gMSAtIChzZXJpZXNJZHhbZFtzZXJpZXNdIGFzIHN0cmluZ10gLyBNYXRoLm1heChuIC0gMSwgMSkpICogMC4yXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxpbmVPcHRzID0ge1xuICAgICAgICBjdXJ2ZSxcbiAgICAgICAgeDogZ2V0WCBhcyAoZDogVCkgPT4gdW5rbm93bixcbiAgICAgICAgeTogZ2V0WSxcbiAgICAgICAgLi4uKGhhc1NlcmllcyAmJiB7IHo6IGdldFogYXMgKGQ6IFQpID0+IHVua25vd24gfSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGxvdCA9IFBsb3QucGxvdCh7XG4gICAgICAgIC4uLkNIQVJUX01BUkdJTlMsXG4gICAgICAgIGhlaWdodDogZGltcy5oLFxuICAgICAgICBtYXJrczogW1xuICAgICAgICAgIC4uLihzaG93QXJlYVxuICAgICAgICAgICAgPyBbXG4gICAgICAgICAgICAgICAgUGxvdC5hcmVhWShkYXRhLCB7XG4gICAgICAgICAgICAgICAgICAuLi5saW5lT3B0cyxcbiAgICAgICAgICAgICAgICAgIGZpbGw6IHN0cm9rZUNvbG9yLFxuICAgICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDAuMTUsXG4gICAgICAgICAgICAgICAgICB5MTogeURvbWFpblswXVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIDogW10pLFxuICAgICAgICAgIFBsb3QubGluZVkoZGF0YSwge1xuICAgICAgICAgICAgLi4ubGluZU9wdHMsXG4gICAgICAgICAgICBzdHJva2U6ICd0cmFuc3BhcmVudCcsXG4gICAgICAgICAgICBzdHJva2VXaWR0aDogMTZcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBQbG90LmxpbmVZKGRhdGEsIHtcbiAgICAgICAgICAgIC4uLmxpbmVPcHRzLFxuICAgICAgICAgICAgc3Ryb2tlOiBzdHJva2VDb2xvcixcbiAgICAgICAgICAgIHN0cm9rZU9wYWNpdHk6IG9wYWNpdHksXG4gICAgICAgICAgICBzdHJva2VXaWR0aDogMS41XG4gICAgICAgICAgfSlcbiAgICAgICAgXSxcbiAgICAgICAgc3R5bGU6IHsgLi4uQ0hBUlRfU1RZTEUsIGZvbnRTdHJldGNoOiAnZXhwYW5kZWQnIH0sXG4gICAgICAgIHdpZHRoOiBkaW1zLncsXG4gICAgICAgIHg6IHsgbGFiZWw6IG51bGwsIHRpY2tGb3JtYXQ6IGZvcm1hdFgsIHRpY2tzOiB4VGlja3MgfSxcbiAgICAgICAgeToge1xuICAgICAgICAgIGRvbWFpbjogeURvbWFpbixcbiAgICAgICAgICBncmlkOiB0cnVlLFxuICAgICAgICAgIGxhYmVsOiBudWxsLFxuICAgICAgICAgIHRpY2tGb3JtYXQ6IGZvcm1hdFksXG4gICAgICAgICAgdGlja3M6IHlUaWNrc1xuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgICBwbG90LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKCkgPT4gc2V0SG92ZXJlZChwbG90LnZhbHVlIGFzIG51bGwgfCBUKSlcbiAgICAgIHN0eWxlUGxvdChwbG90IGFzIEhUTUxFbGVtZW50KVxuXG4gICAgICBwbG90LnF1ZXJ5U2VsZWN0b3JBbGwoJ2dbYXJpYS1sYWJlbD1cImxpbmVcIl0gcGF0aCcpLmZvckVhY2goZWwgPT5cbiAgICAgICAgT2JqZWN0LmFzc2lnbigoZWwgYXMgU1ZHUGF0aEVsZW1lbnQpLnN0eWxlLCB7XG4gICAgICAgICAgdHJhbnNpdGlvbjogJ3N0cm9rZS1vcGFjaXR5IDAuMnMnXG4gICAgICAgIH0pXG4gICAgICApXG5cbiAgICAgIHBsb3RSZWYuY3VycmVudC5hcHBlbmRDaGlsZChwbG90KVxuXG4gICAgICBjb25zdCBjbGVhbnVwID0gc2V0dXBDcm9zc2hhaXIoXG4gICAgICAgIHJlZi5jdXJyZW50LFxuICAgICAgICBkYXRhLFxuICAgICAgICBkID0+IGdldFgoZCkgYXMgbnVtYmVyLFxuICAgICAgICBnZXRZLFxuICAgICAgICB5RG9tYWluLFxuICAgICAgICBkID0+IGZvcm1hdFRvb2x0aXA/LihkKSA/PyBgJHtmb3JtYXRYKGdldFgoZCkpfTogJHtmb3JtYXRZKGdldFkoZCkpfWAsXG4gICAgICAgIHNldENyb3NzaGFpcixcbiAgICAgICAgaGFzU2VyaWVzID8gZCA9PiBnZXRaKGQpIDogdW5kZWZpbmVkXG4gICAgICApXG5cbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNsZWFudXAoKVxuICAgICAgICBwbG90LnBhcmVudE5vZGUgJiYgcGxvdC5yZW1vdmUoKVxuICAgICAgfVxuICAgIH0sIFtcbiAgICAgIGN1cnZlLFxuICAgICAgZGF0YSxcbiAgICAgIGRpbXMuaCxcbiAgICAgIGRpbXMudyxcbiAgICAgIGZvcm1hdFRvb2x0aXAsXG4gICAgICBmb3JtYXRYLFxuICAgICAgZm9ybWF0WSxcbiAgICAgIGdldFgsXG4gICAgICBnZXRZLFxuICAgICAgZ2V0WixcbiAgICAgIGhvdmVyZWQsXG4gICAgICBzZXJpZXMsXG4gICAgICBzaG93QXJlYSxcbiAgICAgIHN0cm9rZUNvbG9yLFxuICAgICAgeFRpY2tzLFxuICAgICAgeURvbWFpbixcbiAgICAgIHlUaWNrc1xuICAgIF0pXG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdlxuICAgICAgICBjbGFzc05hbWU9e2NuKCdyZWxhdGl2ZSBhc3BlY3QtNC8xIHctZnVsbCBvdmVyZmxvdy1jbGlwJywgY2xhc3NOYW1lKX1cbiAgICAgICAgcmVmPXtyZWZ9XG4gICAgICAgIHsuLi5wcm9wc31cbiAgICAgID5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJhYnNvbHV0ZSBpbnNldC0wXCIgcmVmPXtwbG90UmVmfSAvPlxuXG4gICAgICAgIDxDcm9zc2hhaXJcbiAgICAgICAgICBjb2xvcj17c3Ryb2tlQ29sb3J9XG4gICAgICAgICAgY29udGFpbmVyV2lkdGg9e2RpbXMud31cbiAgICAgICAgICBoZWlnaHQ9e2RpbXMuaH1cbiAgICAgICAgICB7Li4uY3Jvc3NoYWlyfVxuICAgICAgICAvPlxuICAgICAgPC9kaXY+XG4gICAgKVxuICB9XG4pXG5cbmludGVyZmFjZSBMaW5lQ2hhcnRQcm9wczxUIGV4dGVuZHMgRGF0YVBvaW50PiBleHRlbmRzIENoYXJ0UHJvcHM8VD4ge1xuICBjdXJ2ZT86ICdiYXNpcycgfCAnY2F0bXVsbC1yb20nIHwgJ2xpbmVhcicgfCAnbmF0dXJhbCcgfCAnc3RlcCdcbiAgc2VyaWVzPzoga2V5b2YgVFxuICBzaG93QXJlYT86IGJvb2xlYW5cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUE4TE0sU0FL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
@@ -0,0 +1,52 @@
1
+ import { type ComponentType, type HTMLAttributes, type RefObject } from 'react';
2
+ import { type BlendColors, type BlendModeProps } from '../blend-mode';
3
+ export declare const accessor: <T, R>(key: ((d: T) => R) | keyof T) => (d: T) => R;
4
+ export declare const CHART_MARGINS: {
5
+ readonly marginBottom: 24;
6
+ readonly marginLeft: 36;
7
+ readonly marginRight: 12;
8
+ readonly marginTop: 8;
9
+ };
10
+ export declare const CHART_STYLE: {
11
+ readonly background: "transparent";
12
+ readonly color: "var(--midground)";
13
+ readonly fontFamily: "var(--font-mono), monospace";
14
+ readonly fontSize: "11px";
15
+ readonly overflow: "hidden";
16
+ };
17
+ export declare const stylePlot: (plot: HTMLElement) => void;
18
+ export declare const useDims: (ref: RefObject<HTMLElement | null>) => {
19
+ h: number;
20
+ w: number;
21
+ };
22
+ export declare const Crosshair: ({ color, containerWidth, height, points, x }: CrosshairState & {
23
+ color?: string;
24
+ containerWidth: number;
25
+ height: number;
26
+ }) => import("react").JSX.Element | null;
27
+ export declare const setupCrosshair: <T extends DataPoint>(container: HTMLElement, data: T[], getX: (d: T) => number, getY: (d: T) => number, yDomain: [number, number], formatTooltip: (d: T) => string, onUpdate: (state: CrosshairState) => void, getZ?: (d: T) => unknown) => () => void;
28
+ export declare const withChartBlend: <P extends BlendModeProps>(Component: ComponentType<P>) => {
29
+ (props: Omit<P, keyof BlendColors>): import("react").JSX.Element;
30
+ displayName: string;
31
+ };
32
+ export type DataPoint = Record<string, unknown>;
33
+ export interface CrosshairPoint {
34
+ dotY: number;
35
+ tooltip: string;
36
+ }
37
+ export interface CrosshairState {
38
+ points?: CrosshairPoint[];
39
+ x: null | number;
40
+ }
41
+ export interface ChartProps<T = DataPoint> extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
42
+ data?: T[];
43
+ formatTooltip?: (d: T) => string;
44
+ formatX?: (v: unknown) => string;
45
+ formatY?: (v: number) => string;
46
+ height?: number;
47
+ x?: ((d: T) => unknown) | keyof T;
48
+ xTicks?: number | number[];
49
+ y?: ((d: T) => number) | keyof T;
50
+ yDomain?: [number, number];
51
+ yTicks?: number | number[];
52
+ }