@seekalfred/primitives 0.6.0 → 0.7.3

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 (346) hide show
  1. package/README.md +214 -15
  2. package/dist/activity-heatmap/activity-heatmap.d.ts +92 -0
  3. package/dist/activity-heatmap/activity-heatmap.js +699 -0
  4. package/dist/activity-heatmap/activity-heatmap.js.map +1 -0
  5. package/dist/activity-heatmap/index.d.ts +2 -0
  6. package/dist/activity-heatmap/index.js +2 -0
  7. package/dist/alert/alert.d.ts +53 -4
  8. package/dist/alert/alert.js +100 -11
  9. package/dist/alert/alert.js.map +1 -1
  10. package/dist/alert/index.d.ts +2 -2
  11. package/dist/alert/index.js +2 -2
  12. package/dist/alert-dialog/alert-dialog.d.ts +58 -18
  13. package/dist/alert-dialog/alert-dialog.js +152 -9
  14. package/dist/alert-dialog/alert-dialog.js.map +1 -1
  15. package/dist/alert-dialog/index.d.ts +2 -2
  16. package/dist/alert-dialog/index.js +2 -2
  17. package/dist/animated-counter/animated-counter.d.ts +38 -0
  18. package/dist/animated-counter/animated-counter.js +230 -0
  19. package/dist/animated-counter/animated-counter.js.map +1 -0
  20. package/dist/animated-counter/index.d.ts +2 -0
  21. package/dist/animated-counter/index.js +2 -0
  22. package/dist/announcement-bar/announcement-bar.d.ts +67 -0
  23. package/dist/announcement-bar/announcement-bar.js +364 -0
  24. package/dist/announcement-bar/announcement-bar.js.map +1 -0
  25. package/dist/announcement-bar/index.d.ts +2 -0
  26. package/dist/announcement-bar/index.js +2 -0
  27. package/dist/badge/badge.d.ts +1 -1
  28. package/dist/bar-chart/bar-chart.d.ts +51 -0
  29. package/dist/bar-chart/bar-chart.js +565 -0
  30. package/dist/bar-chart/bar-chart.js.map +1 -0
  31. package/dist/bar-chart/index.d.ts +2 -0
  32. package/dist/bar-chart/index.js +2 -0
  33. package/dist/breadcrumb/breadcrumb.d.ts +2 -2
  34. package/dist/breadcrumb/breadcrumb.js +12 -3
  35. package/dist/breadcrumb/breadcrumb.js.map +1 -1
  36. package/dist/brush-chart/brush-chart.d.ts +64 -0
  37. package/dist/brush-chart/brush-chart.js +1056 -0
  38. package/dist/brush-chart/brush-chart.js.map +1 -0
  39. package/dist/brush-chart/index.d.ts +2 -0
  40. package/dist/brush-chart/index.js +2 -0
  41. package/dist/button/button.d.ts +1 -1
  42. package/dist/button/button.js +31 -21
  43. package/dist/button/button.js.map +1 -1
  44. package/dist/button-group/button-group.js +3 -4
  45. package/dist/button-group/button-group.js.map +1 -1
  46. package/dist/calendar/calendar.d.ts +1 -1
  47. package/dist/card/card.d.ts +22 -1
  48. package/dist/card/card.js +60 -7
  49. package/dist/card/card.js.map +1 -1
  50. package/dist/card-stack/card-stack.d.ts +54 -0
  51. package/dist/card-stack/card-stack.js +492 -0
  52. package/dist/card-stack/card-stack.js.map +1 -0
  53. package/dist/card-stack/index.d.ts +2 -0
  54. package/dist/card-stack/index.js +2 -0
  55. package/dist/carousel/carousel.d.ts +77 -0
  56. package/dist/carousel/carousel.js +415 -0
  57. package/dist/carousel/carousel.js.map +1 -0
  58. package/dist/carousel/index.d.ts +2 -0
  59. package/dist/carousel/index.js +2 -0
  60. package/dist/checkbox/checkbox.js +4 -4
  61. package/dist/checkbox/checkbox.js.map +1 -1
  62. package/dist/chip-group/chip-group.d.ts +37 -0
  63. package/dist/chip-group/chip-group.js +148 -0
  64. package/dist/chip-group/chip-group.js.map +1 -0
  65. package/dist/chip-group/index.d.ts +2 -0
  66. package/dist/chip-group/index.js +2 -0
  67. package/dist/copy-button/copy-button.d.ts +18 -2
  68. package/dist/copy-button/copy-button.js +29 -8
  69. package/dist/copy-button/copy-button.js.map +1 -1
  70. package/dist/countdown/countdown.d.ts +45 -0
  71. package/dist/countdown/countdown.js +298 -0
  72. package/dist/countdown/countdown.js.map +1 -0
  73. package/dist/countdown/index.d.ts +2 -0
  74. package/dist/countdown/index.js +2 -0
  75. package/dist/date-picker/picker-parts.js +1 -1
  76. package/dist/date-picker/picker-parts.js.map +1 -1
  77. package/dist/dialog/dialog.js +1 -1
  78. package/dist/dialog/dialog.js.map +1 -1
  79. package/dist/donut-chart/donut-chart.d.ts +86 -0
  80. package/dist/donut-chart/donut-chart.js +593 -0
  81. package/dist/donut-chart/donut-chart.js.map +1 -0
  82. package/dist/donut-chart/index.d.ts +2 -0
  83. package/dist/donut-chart/index.js +2 -0
  84. package/dist/empty-state/empty-state.d.ts +42 -10
  85. package/dist/empty-state/empty-state.js +44 -26
  86. package/dist/empty-state/empty-state.js.map +1 -1
  87. package/dist/empty-state/index.d.ts +2 -2
  88. package/dist/empty-state/index.js +2 -2
  89. package/dist/file-drop-zone/file-drop-zone.js +1 -1
  90. package/dist/file-drop-zone/file-drop-zone.js.map +1 -1
  91. package/dist/filter-bar/filter-bar.d.ts +50 -26
  92. package/dist/filter-bar/filter-bar.js +317 -157
  93. package/dist/filter-bar/filter-bar.js.map +1 -1
  94. package/dist/gauge/gauge.d.ts +45 -0
  95. package/dist/gauge/gauge.js +219 -0
  96. package/dist/gauge/gauge.js.map +1 -0
  97. package/dist/gauge/index.d.ts +2 -0
  98. package/dist/gauge/index.js +2 -0
  99. package/dist/in-view-title/in-view-title.d.ts +33 -0
  100. package/dist/in-view-title/in-view-title.js +119 -0
  101. package/dist/in-view-title/in-view-title.js.map +1 -0
  102. package/dist/in-view-title/index.d.ts +2 -0
  103. package/dist/in-view-title/index.js +2 -0
  104. package/dist/index.d.ts +53 -10
  105. package/dist/index.js +52 -12
  106. package/dist/input/input.js +4 -4
  107. package/dist/input/input.js.map +1 -1
  108. package/dist/lib/cn.js +11 -1
  109. package/dist/lib/cn.js.map +1 -1
  110. package/dist/lib/field-message.js +28 -10
  111. package/dist/lib/field-message.js.map +1 -1
  112. package/dist/lib/field-shell.js +10 -3
  113. package/dist/lib/field-shell.js.map +1 -1
  114. package/dist/lib/field-surface.js +31 -9
  115. package/dist/lib/field-surface.js.map +1 -1
  116. package/dist/lib/flag-emoji.js +50 -0
  117. package/dist/lib/flag-emoji.js.map +1 -0
  118. package/dist/lib/flip.js +11 -3
  119. package/dist/lib/flip.js.map +1 -1
  120. package/dist/lib/menu-highlight.js +64 -0
  121. package/dist/lib/menu-highlight.js.map +1 -0
  122. package/dist/lib/motion.js +9 -2
  123. package/dist/lib/motion.js.map +1 -1
  124. package/dist/lib/rolling-value.js +1 -1
  125. package/dist/lib/rolling-value.js.map +1 -1
  126. package/dist/lib/spring-tween.js +500 -0
  127. package/dist/lib/spring-tween.js.map +1 -0
  128. package/dist/lib/swap-text.js +3 -1
  129. package/dist/lib/swap-text.js.map +1 -1
  130. package/dist/lib/use-copy-feedback.js +17 -3
  131. package/dist/lib/use-copy-feedback.js.map +1 -1
  132. package/dist/line-chart/index.d.ts +2 -0
  133. package/dist/line-chart/index.js +2 -0
  134. package/dist/line-chart/line-chart.d.ts +116 -0
  135. package/dist/line-chart/line-chart.js +740 -0
  136. package/dist/line-chart/line-chart.js.map +1 -0
  137. package/dist/mention-input/index.d.ts +2 -0
  138. package/dist/mention-input/index.js +2 -0
  139. package/dist/mention-input/mention-input.d.ts +98 -0
  140. package/dist/mention-input/mention-input.js +576 -0
  141. package/dist/mention-input/mention-input.js.map +1 -0
  142. package/dist/menu/menu.d.ts +2 -0
  143. package/dist/menu/menu.js +23 -12
  144. package/dist/menu/menu.js.map +1 -1
  145. package/dist/money-input/index.d.ts +2 -0
  146. package/dist/money-input/index.js +2 -0
  147. package/dist/money-input/money-input.d.ts +86 -0
  148. package/dist/money-input/money-input.js +613 -0
  149. package/dist/money-input/money-input.js.map +1 -0
  150. package/dist/morph-select/index.d.ts +2 -0
  151. package/dist/morph-select/index.js +2 -0
  152. package/dist/morph-select/morph-select.d.ts +89 -0
  153. package/dist/morph-select/morph-select.js +712 -0
  154. package/dist/morph-select/morph-select.js.map +1 -0
  155. package/dist/multi-select/index.d.ts +2 -0
  156. package/dist/multi-select/index.js +2 -0
  157. package/dist/multi-select/multi-select.d.ts +77 -0
  158. package/dist/multi-select/multi-select.js +209 -0
  159. package/dist/multi-select/multi-select.js.map +1 -0
  160. package/dist/number-field/index.d.ts +2 -0
  161. package/dist/number-field/index.js +2 -0
  162. package/dist/number-field/number-field.d.ts +42 -0
  163. package/dist/number-field/number-field.js +199 -0
  164. package/dist/number-field/number-field.js.map +1 -0
  165. package/dist/onboarding-checklist/index.d.ts +2 -0
  166. package/dist/onboarding-checklist/index.js +2 -0
  167. package/dist/onboarding-checklist/onboarding-checklist.d.ts +55 -0
  168. package/dist/onboarding-checklist/onboarding-checklist.js +577 -0
  169. package/dist/onboarding-checklist/onboarding-checklist.js.map +1 -0
  170. package/dist/password-field/password-field.d.ts +16 -0
  171. package/dist/password-field/password-field.js +39 -10
  172. package/dist/password-field/password-field.js.map +1 -1
  173. package/dist/phone-input/index.d.ts +3 -0
  174. package/dist/phone-input/index.js +3 -0
  175. package/dist/phone-input/phone-countries.d.ts +29 -0
  176. package/dist/phone-input/phone-countries.js +170 -0
  177. package/dist/phone-input/phone-countries.js.map +1 -0
  178. package/dist/phone-input/phone-input.d.ts +66 -0
  179. package/dist/phone-input/phone-input.js +440 -0
  180. package/dist/phone-input/phone-input.js.map +1 -0
  181. package/dist/popover/index.d.ts +2 -2
  182. package/dist/popover/index.js +2 -2
  183. package/dist/popover/popover.d.ts +51 -2
  184. package/dist/popover/popover.js +59 -8
  185. package/dist/popover/popover.js.map +1 -1
  186. package/dist/progress/progress.d.ts +16 -2
  187. package/dist/progress/progress.js +16 -9
  188. package/dist/progress/progress.js.map +1 -1
  189. package/dist/radio-group/index.d.ts +2 -2
  190. package/dist/radio-group/index.js +2 -2
  191. package/dist/radio-group/radio-group.d.ts +33 -3
  192. package/dist/radio-group/radio-group.js +110 -10
  193. package/dist/radio-group/radio-group.js.map +1 -1
  194. package/dist/reactions/index.d.ts +2 -0
  195. package/dist/reactions/index.js +2 -0
  196. package/dist/reactions/reactions.d.ts +50 -0
  197. package/dist/reactions/reactions.js +315 -0
  198. package/dist/reactions/reactions.js.map +1 -0
  199. package/dist/rich-text-editor/index.d.ts +3 -0
  200. package/dist/rich-text-editor/index.js +2 -0
  201. package/dist/rich-text-editor/rich-text-editor.d.ts +70 -0
  202. package/dist/rich-text-editor/rich-text-editor.js +909 -0
  203. package/dist/rich-text-editor/rich-text-editor.js.map +1 -0
  204. package/dist/rich-text-editor/rich-text-engine.d.ts +16 -0
  205. package/dist/rich-text-editor/rich-text-engine.js +366 -0
  206. package/dist/rich-text-editor/rich-text-engine.js.map +1 -0
  207. package/dist/rich-text-editor/rich-text-html.js +174 -0
  208. package/dist/rich-text-editor/rich-text-html.js.map +1 -0
  209. package/dist/rich-text-editor/rich-text-icons.js +43 -0
  210. package/dist/rich-text-editor/rich-text-icons.js.map +1 -0
  211. package/dist/ridgeline/index.d.ts +2 -0
  212. package/dist/ridgeline/index.js +2 -0
  213. package/dist/ridgeline/ridgeline.d.ts +55 -0
  214. package/dist/ridgeline/ridgeline.js +701 -0
  215. package/dist/ridgeline/ridgeline.js.map +1 -0
  216. package/dist/scroll-area/index.d.ts +2 -2
  217. package/dist/scroll-area/index.js +2 -2
  218. package/dist/scroll-area/scroll-area.d.ts +68 -31
  219. package/dist/scroll-area/scroll-area.js +212 -62
  220. package/dist/scroll-area/scroll-area.js.map +1 -1
  221. package/dist/scrub-input/evaluate.d.ts +14 -0
  222. package/dist/scrub-input/evaluate.js +72 -0
  223. package/dist/scrub-input/evaluate.js.map +1 -0
  224. package/dist/scrub-input/index.d.ts +3 -0
  225. package/dist/scrub-input/index.js +3 -0
  226. package/dist/scrub-input/scrub-input.d.ts +74 -0
  227. package/dist/scrub-input/scrub-input.js +486 -0
  228. package/dist/scrub-input/scrub-input.js.map +1 -0
  229. package/dist/search-field/search-field.d.ts +24 -2
  230. package/dist/search-field/search-field.js +24 -9
  231. package/dist/search-field/search-field.js.map +1 -1
  232. package/dist/select/select.d.ts +3 -1
  233. package/dist/select/select.js +28 -14
  234. package/dist/select/select.js.map +1 -1
  235. package/dist/separator/separator.d.ts +22 -10
  236. package/dist/separator/separator.js +33 -11
  237. package/dist/separator/separator.js.map +1 -1
  238. package/dist/sheet/sheet.js +2 -1
  239. package/dist/sheet/sheet.js.map +1 -1
  240. package/dist/shortcut-recorder/index.d.ts +3 -0
  241. package/dist/shortcut-recorder/index.js +3 -0
  242. package/dist/shortcut-recorder/shortcut-model.d.ts +27 -0
  243. package/dist/shortcut-recorder/shortcut-model.js +206 -0
  244. package/dist/shortcut-recorder/shortcut-model.js.map +1 -0
  245. package/dist/shortcut-recorder/shortcut-recorder.d.ts +93 -0
  246. package/dist/shortcut-recorder/shortcut-recorder.js +489 -0
  247. package/dist/shortcut-recorder/shortcut-recorder.js.map +1 -0
  248. package/dist/slider/index.d.ts +2 -2
  249. package/dist/slider/slider.d.ts +46 -14
  250. package/dist/slider/slider.js +151 -67
  251. package/dist/slider/slider.js.map +1 -1
  252. package/dist/slope-chart/index.d.ts +2 -0
  253. package/dist/slope-chart/index.js +2 -0
  254. package/dist/slope-chart/slope-chart.d.ts +54 -0
  255. package/dist/slope-chart/slope-chart.js +568 -0
  256. package/dist/slope-chart/slope-chart.js.map +1 -0
  257. package/dist/sparkline/index.d.ts +2 -0
  258. package/dist/sparkline/index.js +2 -0
  259. package/dist/sparkline/sparkline.d.ts +46 -0
  260. package/dist/sparkline/sparkline.js +390 -0
  261. package/dist/sparkline/sparkline.js.map +1 -0
  262. package/dist/split-bar/index.d.ts +2 -0
  263. package/dist/split-bar/index.js +2 -0
  264. package/dist/split-bar/split-bar.d.ts +62 -0
  265. package/dist/split-bar/split-bar.js +513 -0
  266. package/dist/split-bar/split-bar.js.map +1 -0
  267. package/dist/split-button/split-button.d.ts +1 -1
  268. package/dist/split-button/split-button.js +12 -11
  269. package/dist/split-button/split-button.js.map +1 -1
  270. package/dist/stat-card/index.d.ts +2 -2
  271. package/dist/stat-card/index.js +2 -2
  272. package/dist/stat-card/stat-card.d.ts +58 -5
  273. package/dist/stat-card/stat-card.js +144 -17
  274. package/dist/stat-card/stat-card.js.map +1 -1
  275. package/dist/stepper/index.d.ts +2 -0
  276. package/dist/stepper/index.js +2 -0
  277. package/dist/stepper/stepper.d.ts +51 -0
  278. package/dist/stepper/stepper.js +215 -0
  279. package/dist/stepper/stepper.js.map +1 -0
  280. package/dist/streamgraph/index.d.ts +2 -0
  281. package/dist/streamgraph/index.js +2 -0
  282. package/dist/streamgraph/streamgraph.d.ts +70 -0
  283. package/dist/streamgraph/streamgraph.js +613 -0
  284. package/dist/streamgraph/streamgraph.js.map +1 -0
  285. package/dist/styles.css +1 -1
  286. package/dist/swipe-actions/index.d.ts +2 -0
  287. package/dist/swipe-actions/index.js +2 -0
  288. package/dist/swipe-actions/swipe-actions.d.ts +67 -0
  289. package/dist/swipe-actions/swipe-actions.js +552 -0
  290. package/dist/swipe-actions/swipe-actions.js.map +1 -0
  291. package/dist/switch/switch.js +2 -2
  292. package/dist/switch/switch.js.map +1 -1
  293. package/dist/table/index.d.ts +2 -2
  294. package/dist/table/index.js +2 -2
  295. package/dist/table/table.d.ts +55 -3
  296. package/dist/table/table.js +340 -165
  297. package/dist/table/table.js.map +1 -1
  298. package/dist/tabs/tabs.js +2 -2
  299. package/dist/tabs/tabs.js.map +1 -1
  300. package/dist/tag-input/index.d.ts +2 -0
  301. package/dist/tag-input/index.js +2 -0
  302. package/dist/tag-input/tag-input.d.ts +40 -0
  303. package/dist/tag-input/tag-input.js +269 -0
  304. package/dist/tag-input/tag-input.js.map +1 -0
  305. package/dist/text-morph/index.d.ts +2 -0
  306. package/dist/text-morph/index.js +2 -0
  307. package/dist/text-morph/text-morph.d.ts +23 -0
  308. package/dist/text-morph/text-morph.js +21 -0
  309. package/dist/text-morph/text-morph.js.map +1 -0
  310. package/dist/text-reveal/index.d.ts +2 -0
  311. package/dist/text-reveal/index.js +2 -0
  312. package/dist/text-reveal/text-reveal.d.ts +27 -0
  313. package/dist/text-reveal/text-reveal.js +51 -0
  314. package/dist/text-reveal/text-reveal.js.map +1 -0
  315. package/dist/text-shimmer/index.d.ts +2 -0
  316. package/dist/text-shimmer/index.js +2 -0
  317. package/dist/text-shimmer/text-shimmer.d.ts +29 -0
  318. package/dist/text-shimmer/text-shimmer.js +29 -0
  319. package/dist/text-shimmer/text-shimmer.js.map +1 -0
  320. package/dist/time-picker/time-picker.d.ts +36 -1
  321. package/dist/time-picker/time-picker.js +35 -7
  322. package/dist/time-picker/time-picker.js.map +1 -1
  323. package/dist/toast/index.d.ts +2 -2
  324. package/dist/toast/index.js +2 -2
  325. package/dist/toast/toast.d.ts +7 -1
  326. package/dist/toast/toast.js +82 -40
  327. package/dist/toast/toast.js.map +1 -1
  328. package/dist/tooltip/tooltip.d.ts +9 -2
  329. package/dist/tooltip/tooltip.js +7 -7
  330. package/dist/tooltip/tooltip.js.map +1 -1
  331. package/dist/treemap/index.d.ts +2 -0
  332. package/dist/treemap/index.js +2 -0
  333. package/dist/treemap/treemap.d.ts +53 -0
  334. package/dist/treemap/treemap.js +699 -0
  335. package/dist/treemap/treemap.js.map +1 -0
  336. package/dist/usage-meter/index.d.ts +2 -0
  337. package/dist/usage-meter/index.js +2 -0
  338. package/dist/usage-meter/usage-meter.d.ts +80 -0
  339. package/dist/usage-meter/usage-meter.js +458 -0
  340. package/dist/usage-meter/usage-meter.js.map +1 -0
  341. package/dist/waffle-chart/index.d.ts +2 -0
  342. package/dist/waffle-chart/index.js +2 -0
  343. package/dist/waffle-chart/waffle-chart.d.ts +57 -0
  344. package/dist/waffle-chart/waffle-chart.js +426 -0
  345. package/dist/waffle-chart/waffle-chart.js.map +1 -0
  346. package/package.json +165 -3
package/README.md CHANGED
@@ -132,6 +132,34 @@ makes `description` **required** — React Aria associates the description
132
132
  for that role, so a confirmation built from a plain `Dialog` loses the
133
133
  sentence explaining what is about to happen.
134
134
 
135
+ ### Rich content: `body`
136
+
137
+ `body` puts rich content between the description and the actions: a plan
138
+ comparison, a before/after diff, a quoted reply, a field to fill in or a choice
139
+ to make (a `RadioGroup`). It shares the description's edge and is in the
140
+ dialog's tab order before the actions. `false`, `true` and `""` (as from
141
+ `cond && <X />`) render no body.
142
+
143
+ ```tsx
144
+ <AlertDialog
145
+ isOpen={open}
146
+ onOpenChange={setOpen}
147
+ title="Cancel subscription?"
148
+ description="You keep Pro until the end of the period, then move to Free."
149
+ body={<PlanSummary plan={plan} />}
150
+ >
151
+ <AlertDialogCancel>Keep plan</AlertDialogCancel>
152
+ <AlertDialogAction onPress={cancel}>Cancel subscription</AlertDialogAction>
153
+ </AlertDialog>
154
+ ```
155
+
156
+ The body is not part of the accessible description: a screen reader announces
157
+ only the `description` sentence with the title, and reads the body in place or
158
+ as focus reaches its controls, each with its own label. So a field or a choice
159
+ belongs in `body`, but the `description` must say everything needed to answer,
160
+ including that something below is required ("Pick what happens to your
161
+ recordings, then confirm.").
162
+
135
163
  ### Migrating from the legacy shadcn AlertDialog
136
164
 
137
165
  | legacy | Alfred | |
@@ -224,8 +252,8 @@ A new string label swaps as a whole and the pill's width springs to the new size
224
252
  ```tsx
225
253
  <Breadcrumbs>
226
254
  <BreadcrumbItem href="/">Home</BreadcrumbItem>
227
- <BreadcrumbItem href="/design-thinking">Design Thinking</BreadcrumbItem>
228
- <BreadcrumbItem>User Personas</BreadcrumbItem>
255
+ <BreadcrumbItem href="/design-thinking">Design thinking</BreadcrumbItem>
256
+ <BreadcrumbItem>User personas</BreadcrumbItem>
229
257
  </Breadcrumbs>
230
258
  ```
231
259
 
@@ -528,6 +556,28 @@ Padding is **block-only on the shell and inline-only on the sections**, which
528
556
  is what lets a divider or a full-bleed image run edge to edge. A single `p-6`
529
557
  on the shell would make that impossible.
530
558
 
559
+ ### Featured and flush cards
560
+
561
+ ```tsx
562
+ <Card highlighted>…</Card> {/* the one featured card in a view */}
563
+ <Card flush>…</Card> {/* a table, list or chart that meets the top and bottom */}
564
+ ```
565
+
566
+ `highlighted` replaces the hairline with a brand gradient edge (secondary to
567
+ tertiary, so it follows the theme) without changing the card's box. To repaint
568
+ the edge, set the `--card-highlight` custom property on the card element itself
569
+ (`className` or `style` on `Card`): the utility declares it on the card, so a
570
+ value set on an ancestor does not reach it. Use it for one card per view and
571
+ say in the content why it is featured: the edge is decoration. `flush` drops
572
+ the shell's block padding and the gap between parts and clips the content to
573
+ the rounded border, keeping the outline, radius, surface and shadow; a
574
+ `className` padding still wins. The header and footer keep a 24px block
575
+ inset, so their text clears the corner curve; the content stays block-flush.
576
+ Every section keeps its inline padding, so text never sits in the corner, and
577
+ a section's fill (`<CardContent className="bg-muted">`) still reaches the side
578
+ edges because background paints the padding. Both default to `false`, and the two
579
+ compose: a flush featured card keeps its gradient edge.
580
+
531
581
  ### Migrating from the legacy shadcn Card
532
582
 
533
583
  | legacy | Alfred | |
@@ -682,6 +732,16 @@ What a list shows when it has nothing to show: one muted line, centred in a
682
732
  bordered box the width of the list. `action` is an optional next step under the
683
733
  text and is omitted from the DOM when absent.
684
734
 
735
+ `image` is an optional illustration above the icon and the title (an `<img>`,
736
+ an inline SVG or any element). It is centred, shrinks to fit a narrow box and
737
+ keeps its aspect ratio; its size is the artwork's. The slot reserves no space,
738
+ so set the artwork's intrinsic `width` and `height`, or the layout jumps when
739
+ it loads. The slot does not hide it from assistive technology, so name it:
740
+ give an `<img>` an `alt` (`alt=""` when the title already says it all), and an
741
+ inline `<svg>` `role="img"` with an `aria-label`, or `aria-hidden="true"` when
742
+ it is decorative. Omitted from the DOM when absent; `false` (from
743
+ `cond && <img />`) counts as absent.
744
+
685
745
  ### Motion (EmptyState)
686
746
 
687
747
  New optional `icon` settles in once when the state first appears (small and transparent to rest over 480ms); a different icon component later swaps in place. A string message swaps as a whole when it changes and the message column follows its height on the smooth spring. The message now sits in an `empty-state-copy` frame.
@@ -1044,6 +1104,20 @@ default). Native input props apply to the input, and `className` goes to the
1044
1104
  input; `disabled` also disables the toggle, and `aria-invalid` gives the box its
1045
1105
  invalid border. The box shares the field look of `Input` and `Textarea`.
1046
1106
 
1107
+ `error` is `Input`'s prop: error text under the field, announced as an alert,
1108
+ that sets `aria-invalid` and is named in `aria-describedby`. `isRequired` makes
1109
+ the input `required` and shows a required marker (an asterisk, hidden from
1110
+ assistive technology, which hears the input's own `required`) after the label.
1111
+
1112
+ ```tsx
1113
+ <PasswordField
1114
+ label="API secret"
1115
+ isRequired
1116
+ error={errors.secret?.message}
1117
+ {...register("secret")}
1118
+ />
1119
+ ```
1120
+
1047
1121
  **The toggle's name changes with its state and it is also `aria-pressed`**, so a
1048
1122
  screen reader may announce both ("Hide password, pressed"); this is not tested
1049
1123
  with a screen reader. Reduced motion drops every transition and the press.
@@ -1135,9 +1209,18 @@ and no number. `formatOptions` reaches it too, so a currency or "3 of 7" needs n
1135
1209
  second prop. `trackClassName` and `fillClassName` are escape hatches for a colour
1136
1210
  no tone covers.
1137
1211
 
1212
+ `isIndeterminate` draws a segment 40% of the track wide that sweeps across it
1213
+ from the start edge on a loop (right to left in RTL), and announces no value.
1214
+ With `labelHidden` and no `showValue` nothing is printed above the track, so the
1215
+ 6px header gap collapses and the bar sits at the top of its box.
1216
+
1217
+ `showCompletion={false}` keeps a bar from saying "done" at 100%: the fill keeps
1218
+ its tone and no check lands. Use it for a timer-driven estimate that can reach
1219
+ 100% before the work finishes.
1220
+
1138
1221
  ### Motion (Progress)
1139
1222
 
1140
- The fill follows the value on the smooth spring (it was a 200ms ease) and the printed percentage counts to the new number on the same spring, so the number always matches the bar. When a default-toned bar completes it eases to the success colour (after 200ms) and a check lands beside the count; an explicit `tone` is never overridden, and a bar that is full at mount shows its check with no motion. A value that is not a percentage (a price) is shown as it is. A changed string label swaps as a whole.
1223
+ The fill follows the value on the smooth spring (it was a 200ms ease) and the printed percentage counts to the new number on the same spring, so the number always matches the bar. When a default-toned bar completes it eases to the success colour (after 200ms) and a check lands beside the count; an explicit `tone` is never overridden, `showCompletion={false}` turns both off, and a bar that is full at mount shows its check with no motion. An indeterminate segment sweeps the track every 1.6s; under reduced motion it does not travel, and the fill spans the track and pulses slowly instead. A value that is not a percentage (a price) is shown as it is. A changed string label swaps as a whole.
1141
1224
 
1142
1225
  ## RadioGroup
1143
1226
 
@@ -1148,6 +1231,32 @@ The fill follows the value on the smooth spring (it was a 200ms ease) and the pr
1148
1231
  </RadioGroup>
1149
1232
  ```
1150
1233
 
1234
+ ### Card variant
1235
+
1236
+ `variant="card"` draws each choice as a selectable card: the whole card is the
1237
+ target, the title is `children`, and each `Radio` can take a `description` and
1238
+ a decorative `icon`. The group becomes a grid, so the caller sets the columns.
1239
+
1240
+ ```tsx
1241
+ <RadioGroup variant="card" value={mode} onChange={setMode} aria-label="How to run" className="sm:grid-cols-2">
1242
+ <Radio value="draft" icon={<DraftIcon />} description="Save as a draft and review it first.">
1243
+ Draft only
1244
+ </Radio>
1245
+ <Radio value="everywhere" description="Apply to every category now.">
1246
+ Run everywhere
1247
+ </Radio>
1248
+ </RadioGroup>
1249
+ ```
1250
+
1251
+ - The title alone is the option's name; the description is wired as its
1252
+ description (`aria-describedby`), so a screen reader does not run the two
1253
+ together. The icon is `aria-hidden`.
1254
+ - Selected shows twice: a `primary-strong` edge (StatCard's selected pair) and
1255
+ the same dot as the default radio, so it never rests on colour alone.
1256
+ - Keyboard is unchanged: one tab stop, arrow keys move and select. The focus
1257
+ ring is drawn on the card, not the dot.
1258
+ - `description` and `icon` are ignored by the default variant.
1259
+
1151
1260
  ### Migrating from the legacy RadioGroup
1152
1261
 
1153
1262
  | legacy | Alfred | |
@@ -1192,6 +1301,8 @@ New opt-in `fade` (px, default `0` = off, so an area is unchanged) fades the con
1192
1301
 
1193
1302
  ```tsx
1194
1303
  <SearchField label="Search contacts" value={query} onValueChange={setQuery} />
1304
+ <SearchField label="Search tickets" labelHidden size="sm" placeholder="Search tickets"
1305
+ value={query} onValueChange={setQuery} />
1195
1306
  ```
1196
1307
 
1197
1308
  A search input with a clear button. It is controlled: `value` and
@@ -1205,7 +1316,13 @@ animation, and while the button leaves it cannot be pressed or focused. The
1205
1316
  magnifier is muted at rest and takes full contrast while the field has focus or
1206
1317
  a value.
1207
1318
 
1208
- `label` is required and visible; `clearLabel` renames the button (default "Clear
1319
+ `label` is required and visible unless `labelHidden` is set, which keeps it as
1320
+ the input's accessible name (`aria-label`) without printing it — for a toolbar
1321
+ search whose purpose the surrounding UI already shows. That holds inside a
1322
+ React Aria `TextField` too, including one with no `Label` child. `size` (`sm` · `md` ·
1323
+ `lg`, default `md`) takes the same `--density-control-*` height and padding as
1324
+ Input, Select and Button, and `sm` takes Input's 14px text (16px on a touch
1325
+ screen). `clearLabel` renames the button (default "Clear
1209
1326
  search"). Native input props apply to the input, `className` goes to the input,
1210
1327
  and `disabled` also disables the clear button. The browser's own clear button
1211
1328
  and search decoration are hidden. The box shares the field look of `Input`.
@@ -1270,17 +1387,26 @@ only — WCAG 1.4.1. The message is wired into `aria-describedby` for you.
1270
1387
  ```tsx
1271
1388
  <Separator />
1272
1389
  <Separator orientation="vertical" />
1390
+ <Separator orientation="vertical" decorative />
1273
1391
  ```
1274
1392
 
1275
1393
  React Aria renders an `<hr>` horizontally and a `<div role="separator">`
1276
- vertically.
1394
+ vertically. The line is painted with `--color-separator`, the hairline between
1395
+ rows and groups inside a surface, not `--color-border`, which is the surface's
1396
+ own outline.
1397
+
1398
+ `decorative` draws the same line as a plain `aria-hidden` div, for a rule that
1399
+ only spaces inline items (a metadata row) where announcing "separator" between
1400
+ each pair is noise. Leave it off for a line between two groups of content.
1401
+ Other props (`id`, `data-*`, handlers) reach the div in this mode too; a name
1402
+ (`aria-label`, `aria-labelledby`) is dropped.
1277
1403
 
1278
1404
  ### Migrating from the legacy Separator
1279
1405
 
1280
1406
  | legacy | Alfred | |
1281
1407
  | ------------- | --------------- | ------------------------------------------------------------ |
1282
1408
  | `orientation` | `orientation` | unchanged |
1283
- | `decorative` | *no equivalent* | zero call sites; see below |
1409
+ | `decorative` | `decorative` | default flipped to `false`; see below |
1284
1410
 
1285
1411
  **This changes the semantics of all six existing uses.** The legacy defaulted
1286
1412
  to `decorative: true`, rendering `role="none"` — so every divider in the app
@@ -1351,17 +1477,21 @@ The pulse dims a block to about half and back over 1.8s, 11 times (about 20 seco
1351
1477
  ## Slider
1352
1478
 
1353
1479
  ```tsx
1354
- <Slider label="Input volume" defaultValue={40} />
1480
+ <Slider label="Volume" defaultValue={60} formatOptions={{ style: "unit", unit: "percent" }} />
1481
+ <Slider label="Budget" defaultValue={[2200, 8000]} minValue={0} maxValue={10000} step={100} description="Per month" />
1482
+ <Slider label="Volume" step={25} marks={[0, 25, 50, 75, 100].map((v) => ({ value: v, label: `${v}%` }))} start={<Button size="icon" aria-label="Mute">...</Button>} />
1355
1483
  ```
1356
1484
 
1357
1485
  **`label` is required** — all four legacy call sites are unnamed sliders.
1358
1486
 
1487
+ The look follows the design spec: a thin, rounded, light-grey track with a solid ink (`foreground`) fill, and a solid white thumb with a soft shadow. The label sits left and the value right. `value`/`defaultValue` may be a `[low, high]` pair, which gives two thumbs and a range readout ("$2,200 – $8,000"); `description` adds grey helper text; `marks` draws tick dots (a mark with a `label` prints it under the track); `start`/`end` hold content beside the track, such as an icon button.
1488
+
1359
1489
  The thumb is 24×24 (WCAG 2.5.8); the legacy's was 16. `aria-valuetext` comes
1360
1490
  free, so a scrubber can announce a time instead of a raw second count.
1361
1491
 
1362
1492
  ### Motion (Slider)
1363
1493
 
1364
- A value that arrives from outside a drag (a key, a prop, a click on the track) moves the thumb and the fill on the snappy spring; while dragging they stay under the pointer. The thumb swells to 1.16 while held. A bubble with the value rises in over the thumb (from small and blurred) while it is dragged or keyboard focused, and drops away in 120ms; the readout and the bubble roll their value up or down as it changes. The bubble is `aria-hidden`: the output beside the label carries the value. Reduced motion keeps opacity changes only. Not ported: marks, range, the springing catch-up on a click of the track (React Aria starts a drag at once), rubber-banding past the limits and release momentum.
1494
+ A value that arrives from outside a drag (a key, a prop, a click on the track) moves the thumb and the fill on the snappy spring; while dragging they stay under the pointer. The thumb swells to 1.16 while held. A bubble with the value rises in over the thumb (from small and blurred) while it is dragged or keyboard focused, and drops away in 120ms; the readout and the bubble roll their value up or down as it changes. The bubble is `aria-hidden`: the output beside the label carries the value. Reduced motion keeps opacity changes only. Not ported: clicking a mark label to move there, the springing catch-up on a click of the track (React Aria starts a drag at once), rubber-banding past the limits and release momentum.
1365
1495
 
1366
1496
  ## SplitButton
1367
1497
 
@@ -1422,8 +1552,9 @@ The thumb travels on a no-overshoot spring (559ms), stretches 5px toward its tra
1422
1552
 
1423
1553
  **The track colours are not the legacy's, and could not be.** A white thumb
1424
1554
  on `--color-primary` is 2.44:1 and on `--color-muted` is 1.13:1 — both fail
1425
- WCAG 1.4.11. The track is `border` unchecked and `primary-strong` checked,
1426
- which clears 3:1 in both themes.
1555
+ WCAG 1.4.11. The track is `control-edge` unchecked and `primary-strong`
1556
+ checked, which clears 3:1 in both themes. (`control-edge`, not the light
1557
+ page `border`, which is a decorative hairline.)
1427
1558
 
1428
1559
  ## Table
1429
1560
 
@@ -1526,9 +1657,10 @@ already agree on every value that matters:
1526
1657
  | cell padding | 16px / 12px | same |
1527
1658
  | typeface | Satoshi | same |
1528
1659
 
1529
- The text colours were never a gap: the product's `--muted-foreground` is
1530
- `#6B6B78` and its body ink is `#02021e`, which are this system's
1531
- `--color-muted-foreground` and `--color-foreground` exactly. An earlier draft of
1660
+ The text colours were never a gap at the time: the product's
1661
+ `--muted-foreground` (`#6B6B78`) and body ink (`#02021e`) matched this
1662
+ system's `--color-muted-foreground` and `--color-foreground`. Since the 2026
1663
+ colour refresh these roles follow the design tokens (ink 600 and ink 900). An earlier draft of
1532
1664
  this section claimed otherwise and prescribed `#0f172b` / `#6b6b6b`; those come
1533
1665
  from `--table-text-*`, which the AI-visibility tables do not use. Do not apply
1534
1666
  them.
@@ -1591,8 +1723,8 @@ uncommitted form state, a running video or a scroll position will lose it
1591
1723
  on tab change — pass `shouldForceMount` on that `TabPanel`. With 31 legacy
1592
1724
  panels, some will need it.
1593
1725
 
1594
- The selected tab carries a **border**, not just a fill: `bg-background` on
1595
- a `bg-muted` list is 1.13:1, and WCAG 1.4.11 wants 3:1 for the thing
1726
+ The selected tab carries a **border**, not just a fill: a surface on a
1727
+ `bg-muted` list is barely distinguishable, and WCAG 1.4.11 wants 3:1 for the thing
1596
1728
  telling you which tab is active.
1597
1729
 
1598
1730
  ## ThemeSwitch
@@ -1629,6 +1761,28 @@ builds a `Time` at runtime, so the peer dependency is a real import here.
1629
1761
  (1, 5, 10, 15 or 30; a time between steps is added to the list so it is never lost),
1630
1762
  and `hourCycle` chooses 12 or 24 hour times.
1631
1763
 
1764
+ **In a form**: `id` goes on the trigger (so an outside `<label htmlFor>` or a form
1765
+ library reaches it), `name` submits the time as `"HH:MM"` in 24-hour time, as
1766
+ `<input type="time">` does, and `onBlur` fires when focus leaves the trigger.
1767
+ `isInvalid` paints the invalid border and `errorMessage` shows under the control
1768
+ while it is invalid, named in `aria-describedby`, as on `Select`. With
1769
+ react-hook-form, wire them from a `Controller`. Pass `field.value ?? null`, not
1770
+ `field.value`: `undefined` makes the picker uncontrolled, so a form reset to
1771
+ `undefined` would leave the last time on screen, while `null` clears it. With no
1772
+ time chosen, `name` submits an empty string.
1773
+
1774
+ ```tsx
1775
+ <Controller
1776
+ name="syncTime"
1777
+ control={control}
1778
+ render={({ field, fieldState }) => (
1779
+ <TimePicker label="Sync time" id={field.name} name={field.name}
1780
+ value={field.value ?? null} onChange={field.onChange} onBlur={field.onBlur}
1781
+ isInvalid={!!fieldState.error} errorMessage={fieldState.error?.message} />
1782
+ )}
1783
+ />
1784
+ ```
1785
+
1632
1786
  **Motion** (plain CSS and a little plain React, no animation library): the shown
1633
1787
  time rolls like a clock face (a later time rises in from below, an earlier one
1634
1788
  drops in from above, and the old one lifts away); the chevron turns half a turn on
@@ -1681,6 +1835,8 @@ A toast rises 16px from below and grows from .96 on the morph spring while it fa
1681
1835
  </TooltipTrigger>
1682
1836
  ```
1683
1837
 
1838
+ The bubble is solid ink with `background` text (so it inverts in dark mode), a large corner and comfortable padding; long text wraps at 15rem. It opens above its trigger with **no arrow**; `placement` and `showArrow` are opt-in.
1839
+
1684
1840
  **`delay` defaults to 0**, matching the legacy provider. React Aria ships
1685
1841
  1500ms — taking that default would have put a 1.5-second warm-up on every
1686
1842
  tooltip in the app. Focus opens it immediately regardless.
@@ -1699,3 +1855,46 @@ inherits from the document. Set both if you support RTL.
1699
1855
 
1700
1856
  A tooltip rises 3px from its trigger and settles from .97 over 160ms (offset follows the side it opens on), and leaves in 120ms. While any tooltip is open, and for 300ms after the last one closes, the next one only fades in (no travel). The open delay stays 0. Reduced motion fades only. **DOM:** an empty hidden `span` inside the tooltip marks the warm case. Not ported: the crossfade and size spring when a string tooltip's text changes while open.
1701
1857
 
1858
+
1859
+ ## UsageMeter
1860
+
1861
+ ```tsx
1862
+ <UsageMeter label="Workspace storage" segments={segments} limit={10} unit="GB" />
1863
+ ```
1864
+
1865
+ The meter works its state out from the numbers: almost full from `warnAt` (a
1866
+ share of the limit, 0.9 by default), over once the total passes the limit.
1867
+
1868
+ ### A status from the backend
1869
+
1870
+ When the product decides the state, pass `status` and the meter shows that
1871
+ instead of its own reading (badge, `data-status`, the bar's name and the
1872
+ announcement). The bar and legend agree with it:
1873
+
1874
+ - `full` and `exhausted` under the limit mean the allowance is used up, so
1875
+ there is no free share: the bar spans what is used and the free item reads 0.
1876
+ The headline still states the plan size ("7.7 GB of 10 GB used").
1877
+ - Past the limit, `ok` and `warn` give way to the meter's own over state, since
1878
+ the hatch already shows the overage. `full` and `exhausted` keep their words.
1879
+
1880
+ | `status` | meaning | badge | `data-status` |
1881
+ | ----------- | --------------------------- | --------------- | ------------- |
1882
+ | `ok` | under the limit | "N free" | `ok` |
1883
+ | `warn` | almost full | "Almost full" | `near` |
1884
+ | `full` | allowance used up | "Limit reached" | `full` |
1885
+ | `exhausted` | nothing left to draw on | "None left" | `exhausted` |
1886
+
1887
+ `statusLabel` is the product's own words for the status ("Credits paused"). It
1888
+ replaces the badge's words in every mode (including "Unlimited"), the status in
1889
+ the bar's name and the announcement; the tone and icon still follow the status.
1890
+
1891
+ ### Unlimited
1892
+
1893
+ `unlimited` is a plan with no limit. The badge reads "Unlimited" (unless
1894
+ `statusLabel` is set), the bar shows
1895
+ each category's share of what is used, and there is no free share, limit marker
1896
+ or overflow hatch. `limit`, `warnAt` and `status` are ignored.
1897
+
1898
+ ```tsx
1899
+ <UsageMeter label="Keyword slots" segments={segments} limit={0} unlimited />
1900
+ ```
@@ -0,0 +1,92 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/activity-heatmap/activity-heatmap.d.ts
3
+ /**
4
+ * ActivityHeatmap: one square per day, weeks as columns, four tints of the
5
+ * primary chart colour for how busy a day was. Use it when rhythm, streaks and
6
+ * quiet weeks matter more than exact comparisons; use a bar chart when the
7
+ * exact comparison is the point.
8
+ *
9
+ * The squares wave in once, diagonally, when the grid is seen. A tooltip
10
+ * glides between squares on hover or keyboard focus and its words rise in. A
11
+ * new range recolours the grid in a sweep instead of redrawing it, and the
12
+ * total rolls to its new number. The legend's squares preview a level on the
13
+ * grid (the others step back) and pin it on press.
14
+ *
15
+ * It sits in a card (`framed`, on by default). A year switch (`periods`) sits
16
+ * beside the total, and a detail line under the legend says what the hovered,
17
+ * focused or selected day holds (`describeDay`).
18
+ *
19
+ * The grid is a `grid` of `gridcell`s with one tab stop: arrow keys move by
20
+ * day (up and down) and by week (left and right), Home and End jump to the
21
+ * ends, Enter selects. A visually hidden table carries every day.
22
+ */
23
+ export interface ActivityDay {
24
+ /** Calendar day as YYYY-MM-DD. */
25
+ date: string;
26
+ count: number;
27
+ }
28
+ /** What `describeDay` is given for one day. */
29
+ export interface ActivityDayDetail {
30
+ /** The day as YYYY-MM-DD. */
31
+ date: string;
32
+ count: number;
33
+ /** The day spelled out, such as "Tuesday, March 18". The year is added when the range spans more than one. */
34
+ label: string;
35
+ /** The nouns for the count, as passed in `unit`. */
36
+ unit: {
37
+ one: string;
38
+ other: string;
39
+ };
40
+ }
41
+ export interface ActivityHeatmapProps {
42
+ /** One entry per day, oldest first. Days missing inside the range count as zero. */
43
+ days: ActivityDay[];
44
+ /** Accessible name for the grid, such as "Contributions in 2025". */
45
+ label: string;
46
+ /** Finishes the summary line: "1,284 contributions in {period}". */
47
+ period: string;
48
+ /** Nouns for the count. @default { one: "contribution", other: "contributions" } */
49
+ unit?: {
50
+ one: string;
51
+ other: string;
52
+ };
53
+ /** Upper bounds for levels one to three; anything above the last is level four. Defaults to quarters of the busiest day. */
54
+ thresholds?: [number, number, number];
55
+ /** @default 0 (Sunday) */
56
+ weekStartsOn?: 0 | 1;
57
+ /** Controlled selected day, as YYYY-MM-DD. */
58
+ selectedDate?: string | null;
59
+ defaultSelectedDate?: string | null;
60
+ /** Called with the day's YYYY-MM-DD when a day is pressed or chosen with Enter. */
61
+ onSelectDate?: (date: string) => void;
62
+ /** Controls beside the summary. */
63
+ actions?: ReactNode;
64
+ /**
65
+ * The ranges to switch between, such as ["2025", "2024", "2023"], shown as a segmented switch beside the summary with the one
66
+ * equal to `period` selected. You own the data: when `onPeriodChange` fires, pass the new `days`, `period` and `label`.
67
+ */
68
+ periods?: string[];
69
+ /** Called with the chosen entry of `periods`. */
70
+ onPeriodChange?: (period: string) => void;
71
+ /** Accessible name for the switch. @default "Period" */
72
+ periodsLabel?: string;
73
+ /**
74
+ * The sentence under the legend about the hovered, focused or selected day. Return the whole sentence, so it can carry data
75
+ * the heatmap does not hold. Pass `null` to remove the line. The default is date and count only:
76
+ * "Tuesday, March 18: 4 contributions."
77
+ */
78
+ describeDay?: ((day: ActivityDayDetail) => string) | null;
79
+ /** The detail line when no day is hovered, focused or selected. @default "Hover or select a day for details." */
80
+ detailHint?: string;
81
+ /** Draws the card around it: border, panel radius, surface and padding. Turn it off to place the heatmap inside a card of your own. @default true */
82
+ framed?: boolean;
83
+ /** Shown instead of the grid when there are no days. @default "No activity yet" */
84
+ emptyLabel?: string;
85
+ /** Formatting locale. Fixed by default so server and client render the same labels. @default "en-US" */
86
+ locale?: string;
87
+ /** Extra classes for the root. Merged last. */
88
+ className?: string;
89
+ }
90
+ export declare const ActivityHeatmap: import("react").ForwardRefExoticComponent<ActivityHeatmapProps & import("react").RefAttributes<HTMLDivElement>>;
91
+ //#endregion
92
+ //# sourceMappingURL=activity-heatmap.d.ts.map