@seekalfred/primitives 0.5.1 → 0.7.1

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 (446) hide show
  1. package/README.md +682 -19
  2. package/dist/accordion/accordion.js +10 -4
  3. package/dist/accordion/accordion.js.map +1 -1
  4. package/dist/action-button/action-button.d.ts +50 -0
  5. package/dist/action-button/action-button.js +159 -0
  6. package/dist/action-button/action-button.js.map +1 -0
  7. package/dist/action-button/index.d.ts +2 -0
  8. package/dist/action-button/index.js +2 -0
  9. package/dist/activity-heatmap/activity-heatmap.d.ts +92 -0
  10. package/dist/activity-heatmap/activity-heatmap.js +699 -0
  11. package/dist/activity-heatmap/activity-heatmap.js.map +1 -0
  12. package/dist/activity-heatmap/index.d.ts +2 -0
  13. package/dist/activity-heatmap/index.js +2 -0
  14. package/dist/alert/alert.d.ts +19 -1
  15. package/dist/alert/alert.js +180 -23
  16. package/dist/alert/alert.js.map +1 -1
  17. package/dist/alert-dialog/alert-dialog.d.ts +45 -18
  18. package/dist/alert-dialog/alert-dialog.js +128 -9
  19. package/dist/alert-dialog/alert-dialog.js.map +1 -1
  20. package/dist/alert-dialog/index.d.ts +2 -2
  21. package/dist/alert-dialog/index.js +2 -2
  22. package/dist/animated-counter/animated-counter.d.ts +38 -0
  23. package/dist/animated-counter/animated-counter.js +230 -0
  24. package/dist/animated-counter/animated-counter.js.map +1 -0
  25. package/dist/animated-counter/index.d.ts +2 -0
  26. package/dist/animated-counter/index.js +2 -0
  27. package/dist/announcement-bar/announcement-bar.d.ts +67 -0
  28. package/dist/announcement-bar/announcement-bar.js +364 -0
  29. package/dist/announcement-bar/announcement-bar.js.map +1 -0
  30. package/dist/announcement-bar/index.d.ts +2 -0
  31. package/dist/announcement-bar/index.js +2 -0
  32. package/dist/avatar/avatar.d.ts +6 -0
  33. package/dist/avatar/avatar.js +47 -16
  34. package/dist/avatar/avatar.js.map +1 -1
  35. package/dist/badge/badge.d.ts +10 -3
  36. package/dist/badge/badge.js +35 -5
  37. package/dist/badge/badge.js.map +1 -1
  38. package/dist/bar-chart/bar-chart.d.ts +51 -0
  39. package/dist/bar-chart/bar-chart.js +565 -0
  40. package/dist/bar-chart/bar-chart.js.map +1 -0
  41. package/dist/bar-chart/index.d.ts +2 -0
  42. package/dist/bar-chart/index.js +2 -0
  43. package/dist/breadcrumb/breadcrumb.d.ts +2 -29
  44. package/dist/breadcrumb/breadcrumb.js +32 -9
  45. package/dist/breadcrumb/breadcrumb.js.map +1 -1
  46. package/dist/brush-chart/brush-chart.d.ts +64 -0
  47. package/dist/brush-chart/brush-chart.js +1056 -0
  48. package/dist/brush-chart/brush-chart.js.map +1 -0
  49. package/dist/brush-chart/index.d.ts +2 -0
  50. package/dist/brush-chart/index.js +2 -0
  51. package/dist/button/button.d.ts +36 -23
  52. package/dist/button/button.js +198 -45
  53. package/dist/button/button.js.map +1 -1
  54. package/dist/button-group/button-group.d.ts +76 -0
  55. package/dist/button-group/button-group.js +402 -0
  56. package/dist/button-group/button-group.js.map +1 -0
  57. package/dist/button-group/index.d.ts +2 -0
  58. package/dist/button-group/index.js +2 -0
  59. package/dist/calendar/calendar.d.ts +1 -1
  60. package/dist/calendar/calendar.js +257 -30
  61. package/dist/calendar/calendar.js.map +1 -1
  62. package/dist/card/card.d.ts +9 -2
  63. package/dist/card/card.js +16 -5
  64. package/dist/card/card.js.map +1 -1
  65. package/dist/card-stack/card-stack.d.ts +54 -0
  66. package/dist/card-stack/card-stack.js +492 -0
  67. package/dist/card-stack/card-stack.js.map +1 -0
  68. package/dist/card-stack/index.d.ts +2 -0
  69. package/dist/card-stack/index.js +2 -0
  70. package/dist/carousel/carousel.d.ts +56 -0
  71. package/dist/carousel/carousel.js +389 -0
  72. package/dist/carousel/carousel.js.map +1 -0
  73. package/dist/carousel/index.d.ts +2 -0
  74. package/dist/carousel/index.js +2 -0
  75. package/dist/checkbox/checkbox.d.ts +0 -7
  76. package/dist/checkbox/checkbox.js +26 -29
  77. package/dist/checkbox/checkbox.js.map +1 -1
  78. package/dist/chip-group/chip-group.d.ts +37 -0
  79. package/dist/chip-group/chip-group.js +148 -0
  80. package/dist/chip-group/chip-group.js.map +1 -0
  81. package/dist/chip-group/index.d.ts +2 -0
  82. package/dist/chip-group/index.js +2 -0
  83. package/dist/confirm-morph/confirm-morph.d.ts +85 -0
  84. package/dist/confirm-morph/confirm-morph.js +652 -0
  85. package/dist/confirm-morph/confirm-morph.js.map +1 -0
  86. package/dist/confirm-morph/index.d.ts +2 -0
  87. package/dist/confirm-morph/index.js +2 -0
  88. package/dist/copy-button/copy-button.d.ts +32 -0
  89. package/dist/copy-button/copy-button.js +134 -0
  90. package/dist/copy-button/copy-button.js.map +1 -0
  91. package/dist/copy-button/index.d.ts +2 -0
  92. package/dist/copy-button/index.js +2 -0
  93. package/dist/countdown/countdown.d.ts +45 -0
  94. package/dist/countdown/countdown.js +298 -0
  95. package/dist/countdown/countdown.js.map +1 -0
  96. package/dist/countdown/index.d.ts +2 -0
  97. package/dist/countdown/index.js +2 -0
  98. package/dist/date-picker/date-picker.d.ts +51 -0
  99. package/dist/date-picker/date-picker.js +241 -0
  100. package/dist/date-picker/date-picker.js.map +1 -0
  101. package/dist/date-picker/date-range-picker.d.ts +78 -0
  102. package/dist/date-picker/date-range-picker.js +1015 -0
  103. package/dist/date-picker/date-range-picker.js.map +1 -0
  104. package/dist/date-picker/index.d.ts +4 -0
  105. package/dist/date-picker/index.js +4 -0
  106. package/dist/date-picker/picker-parts.d.ts +46 -0
  107. package/dist/date-picker/picker-parts.js +135 -0
  108. package/dist/date-picker/picker-parts.js.map +1 -0
  109. package/dist/dialog/dialog.d.ts +10 -14
  110. package/dist/dialog/dialog.js +40 -12
  111. package/dist/dialog/dialog.js.map +1 -1
  112. package/dist/donut-chart/donut-chart.d.ts +64 -0
  113. package/dist/donut-chart/donut-chart.js +576 -0
  114. package/dist/donut-chart/donut-chart.js.map +1 -0
  115. package/dist/donut-chart/index.d.ts +2 -0
  116. package/dist/donut-chart/index.js +2 -0
  117. package/dist/empty-state/empty-state.d.ts +55 -0
  118. package/dist/empty-state/empty-state.js +89 -0
  119. package/dist/empty-state/empty-state.js.map +1 -0
  120. package/dist/empty-state/index.d.ts +2 -0
  121. package/dist/empty-state/index.js +2 -0
  122. package/dist/expanding-button-group/expanding-button-group.d.ts +54 -0
  123. package/dist/expanding-button-group/expanding-button-group.js +350 -0
  124. package/dist/expanding-button-group/expanding-button-group.js.map +1 -0
  125. package/dist/expanding-button-group/index.d.ts +2 -0
  126. package/dist/expanding-button-group/index.js +2 -0
  127. package/dist/file-drop-zone/file-drop-zone.d.ts +71 -0
  128. package/dist/file-drop-zone/file-drop-zone.js +116 -0
  129. package/dist/file-drop-zone/file-drop-zone.js.map +1 -0
  130. package/dist/file-drop-zone/index.d.ts +2 -0
  131. package/dist/file-drop-zone/index.js +2 -0
  132. package/dist/filter-bar/filter-bar.d.ts +142 -0
  133. package/dist/filter-bar/filter-bar.js +416 -0
  134. package/dist/filter-bar/filter-bar.js.map +1 -0
  135. package/dist/filter-bar/index.d.ts +2 -0
  136. package/dist/filter-bar/index.js +2 -0
  137. package/dist/floating-button-group/floating-button-group.d.ts +61 -0
  138. package/dist/floating-button-group/floating-button-group.js +340 -0
  139. package/dist/floating-button-group/floating-button-group.js.map +1 -0
  140. package/dist/floating-button-group/index.d.ts +2 -0
  141. package/dist/floating-button-group/index.js +2 -0
  142. package/dist/gauge/gauge.d.ts +45 -0
  143. package/dist/gauge/gauge.js +219 -0
  144. package/dist/gauge/gauge.js.map +1 -0
  145. package/dist/gauge/index.d.ts +2 -0
  146. package/dist/gauge/index.js +2 -0
  147. package/dist/icon-morph/icon-morph.d.ts +55 -0
  148. package/dist/icon-morph/icon-morph.js +331 -0
  149. package/dist/icon-morph/icon-morph.js.map +1 -0
  150. package/dist/icon-morph/index.d.ts +2 -0
  151. package/dist/icon-morph/index.js +2 -0
  152. package/dist/in-view-title/in-view-title.d.ts +33 -0
  153. package/dist/in-view-title/in-view-title.js +119 -0
  154. package/dist/in-view-title/in-view-title.js.map +1 -0
  155. package/dist/in-view-title/index.d.ts +2 -0
  156. package/dist/in-view-title/index.js +2 -0
  157. package/dist/index.d.ts +71 -6
  158. package/dist/index.js +73 -11
  159. package/dist/input/input.d.ts +22 -0
  160. package/dist/input/input.js +36 -12
  161. package/dist/input/input.js.map +1 -1
  162. package/dist/lib/cn.js +11 -1
  163. package/dist/lib/cn.js.map +1 -1
  164. package/dist/lib/count-to.js +113 -0
  165. package/dist/lib/count-to.js.map +1 -0
  166. package/dist/lib/eye-morph.js +62 -0
  167. package/dist/lib/eye-morph.js.map +1 -0
  168. package/dist/lib/field-message.js +354 -0
  169. package/dist/lib/field-message.js.map +1 -0
  170. package/dist/lib/field-shell.js +81 -0
  171. package/dist/lib/field-shell.js.map +1 -0
  172. package/dist/lib/field-surface.js +11 -8
  173. package/dist/lib/field-surface.js.map +1 -1
  174. package/dist/lib/flag-emoji.js +50 -0
  175. package/dist/lib/flag-emoji.js.map +1 -0
  176. package/dist/lib/flip.js +88 -0
  177. package/dist/lib/flip.js.map +1 -0
  178. package/dist/lib/height-follow.js +59 -0
  179. package/dist/lib/height-follow.js.map +1 -0
  180. package/dist/lib/icon-swap.js +47 -0
  181. package/dist/lib/icon-swap.js.map +1 -0
  182. package/dist/lib/leaving-list.js +57 -0
  183. package/dist/lib/leaving-list.js.map +1 -0
  184. package/dist/lib/menu-highlight.js +64 -0
  185. package/dist/lib/menu-highlight.js.map +1 -0
  186. package/dist/lib/merge-refs.js +3 -3
  187. package/dist/lib/merge-refs.js.map +1 -1
  188. package/dist/lib/morph-text.js +128 -0
  189. package/dist/lib/morph-text.js.map +1 -0
  190. package/dist/lib/motion.js +169 -0
  191. package/dist/lib/motion.js.map +1 -0
  192. package/dist/lib/pausable-timeout.js +67 -0
  193. package/dist/lib/pausable-timeout.js.map +1 -0
  194. package/dist/lib/rolling-value.js +31 -0
  195. package/dist/lib/rolling-value.js.map +1 -0
  196. package/dist/lib/spring-progress.js +114 -0
  197. package/dist/lib/spring-progress.js.map +1 -0
  198. package/dist/lib/spring-tween.js +500 -0
  199. package/dist/lib/spring-tween.js.map +1 -0
  200. package/dist/lib/svg-id.js +10 -0
  201. package/dist/lib/svg-id.js.map +1 -0
  202. package/dist/lib/swap-text.js +79 -0
  203. package/dist/lib/swap-text.js.map +1 -0
  204. package/dist/lib/use-copy-feedback.js +36 -0
  205. package/dist/lib/use-copy-feedback.js.map +1 -0
  206. package/dist/line-chart/index.d.ts +2 -0
  207. package/dist/line-chart/index.js +2 -0
  208. package/dist/line-chart/line-chart.d.ts +76 -0
  209. package/dist/line-chart/line-chart.js +611 -0
  210. package/dist/line-chart/line-chart.js.map +1 -0
  211. package/dist/mention-input/index.d.ts +2 -0
  212. package/dist/mention-input/index.js +2 -0
  213. package/dist/mention-input/mention-input.d.ts +98 -0
  214. package/dist/mention-input/mention-input.js +576 -0
  215. package/dist/mention-input/mention-input.js.map +1 -0
  216. package/dist/menu/menu.d.ts +2 -0
  217. package/dist/menu/menu.js +23 -12
  218. package/dist/menu/menu.js.map +1 -1
  219. package/dist/money-input/index.d.ts +2 -0
  220. package/dist/money-input/index.js +2 -0
  221. package/dist/money-input/money-input.d.ts +65 -0
  222. package/dist/money-input/money-input.js +607 -0
  223. package/dist/money-input/money-input.js.map +1 -0
  224. package/dist/morph-select/index.d.ts +2 -0
  225. package/dist/morph-select/index.js +2 -0
  226. package/dist/morph-select/morph-select.d.ts +71 -0
  227. package/dist/morph-select/morph-select.js +693 -0
  228. package/dist/morph-select/morph-select.js.map +1 -0
  229. package/dist/multi-select/index.d.ts +2 -0
  230. package/dist/multi-select/index.js +2 -0
  231. package/dist/multi-select/multi-select.d.ts +36 -0
  232. package/dist/multi-select/multi-select.js +152 -0
  233. package/dist/multi-select/multi-select.js.map +1 -0
  234. package/dist/number-field/index.d.ts +2 -0
  235. package/dist/number-field/index.js +2 -0
  236. package/dist/number-field/number-field.d.ts +42 -0
  237. package/dist/number-field/number-field.js +199 -0
  238. package/dist/number-field/number-field.js.map +1 -0
  239. package/dist/onboarding-checklist/index.d.ts +2 -0
  240. package/dist/onboarding-checklist/index.js +2 -0
  241. package/dist/onboarding-checklist/onboarding-checklist.d.ts +55 -0
  242. package/dist/onboarding-checklist/onboarding-checklist.js +577 -0
  243. package/dist/onboarding-checklist/onboarding-checklist.js.map +1 -0
  244. package/dist/page-header/index.d.ts +2 -0
  245. package/dist/page-header/index.js +2 -0
  246. package/dist/page-header/page-header.d.ts +75 -0
  247. package/dist/page-header/page-header.js +83 -0
  248. package/dist/page-header/page-header.js.map +1 -0
  249. package/dist/password-field/index.d.ts +2 -0
  250. package/dist/password-field/index.js +2 -0
  251. package/dist/password-field/password-field.d.ts +37 -0
  252. package/dist/password-field/password-field.js +101 -0
  253. package/dist/password-field/password-field.js.map +1 -0
  254. package/dist/password-strength/index.d.ts +2 -0
  255. package/dist/password-strength/index.js +2 -0
  256. package/dist/password-strength/password-strength.d.ts +127 -0
  257. package/dist/password-strength/password-strength.js +455 -0
  258. package/dist/password-strength/password-strength.js.map +1 -0
  259. package/dist/phone-input/index.d.ts +3 -0
  260. package/dist/phone-input/index.js +3 -0
  261. package/dist/phone-input/phone-countries.d.ts +29 -0
  262. package/dist/phone-input/phone-countries.js +170 -0
  263. package/dist/phone-input/phone-countries.js.map +1 -0
  264. package/dist/phone-input/phone-input.d.ts +66 -0
  265. package/dist/phone-input/phone-input.js +440 -0
  266. package/dist/phone-input/phone-input.js.map +1 -0
  267. package/dist/popover/popover.d.ts +20 -0
  268. package/dist/popover/popover.js +33 -9
  269. package/dist/popover/popover.js.map +1 -1
  270. package/dist/progress/progress.js +46 -5
  271. package/dist/progress/progress.js.map +1 -1
  272. package/dist/radio-group/radio-group.js +8 -7
  273. package/dist/radio-group/radio-group.js.map +1 -1
  274. package/dist/reactions/index.d.ts +2 -0
  275. package/dist/reactions/index.js +2 -0
  276. package/dist/reactions/reactions.d.ts +50 -0
  277. package/dist/reactions/reactions.js +315 -0
  278. package/dist/reactions/reactions.js.map +1 -0
  279. package/dist/rich-text-editor/index.d.ts +3 -0
  280. package/dist/rich-text-editor/index.js +2 -0
  281. package/dist/rich-text-editor/rich-text-editor.d.ts +70 -0
  282. package/dist/rich-text-editor/rich-text-editor.js +909 -0
  283. package/dist/rich-text-editor/rich-text-editor.js.map +1 -0
  284. package/dist/rich-text-editor/rich-text-engine.d.ts +16 -0
  285. package/dist/rich-text-editor/rich-text-engine.js +366 -0
  286. package/dist/rich-text-editor/rich-text-engine.js.map +1 -0
  287. package/dist/rich-text-editor/rich-text-html.js +174 -0
  288. package/dist/rich-text-editor/rich-text-html.js.map +1 -0
  289. package/dist/rich-text-editor/rich-text-icons.js +43 -0
  290. package/dist/rich-text-editor/rich-text-icons.js.map +1 -0
  291. package/dist/ridgeline/index.d.ts +2 -0
  292. package/dist/ridgeline/index.js +2 -0
  293. package/dist/ridgeline/ridgeline.d.ts +55 -0
  294. package/dist/ridgeline/ridgeline.js +701 -0
  295. package/dist/ridgeline/ridgeline.js.map +1 -0
  296. package/dist/scroll-area/index.d.ts +2 -2
  297. package/dist/scroll-area/index.js +2 -2
  298. package/dist/scroll-area/scroll-area.d.ts +75 -28
  299. package/dist/scroll-area/scroll-area.js +212 -41
  300. package/dist/scroll-area/scroll-area.js.map +1 -1
  301. package/dist/scrub-input/evaluate.d.ts +14 -0
  302. package/dist/scrub-input/evaluate.js +72 -0
  303. package/dist/scrub-input/evaluate.js.map +1 -0
  304. package/dist/scrub-input/index.d.ts +3 -0
  305. package/dist/scrub-input/index.js +3 -0
  306. package/dist/scrub-input/scrub-input.d.ts +74 -0
  307. package/dist/scrub-input/scrub-input.js +486 -0
  308. package/dist/scrub-input/scrub-input.js.map +1 -0
  309. package/dist/search-field/index.d.ts +2 -0
  310. package/dist/search-field/index.js +2 -0
  311. package/dist/search-field/search-field.d.ts +27 -0
  312. package/dist/search-field/search-field.js +155 -0
  313. package/dist/search-field/search-field.js.map +1 -0
  314. package/dist/select/select.d.ts +3 -1
  315. package/dist/select/select.js +95 -25
  316. package/dist/select/select.js.map +1 -1
  317. package/dist/separator/separator.d.ts +1 -1
  318. package/dist/sheet/sheet.js +4 -2
  319. package/dist/sheet/sheet.js.map +1 -1
  320. package/dist/shortcut-recorder/index.d.ts +3 -0
  321. package/dist/shortcut-recorder/index.js +3 -0
  322. package/dist/shortcut-recorder/shortcut-model.d.ts +27 -0
  323. package/dist/shortcut-recorder/shortcut-model.js +206 -0
  324. package/dist/shortcut-recorder/shortcut-model.js.map +1 -0
  325. package/dist/shortcut-recorder/shortcut-recorder.d.ts +93 -0
  326. package/dist/shortcut-recorder/shortcut-recorder.js +489 -0
  327. package/dist/shortcut-recorder/shortcut-recorder.js.map +1 -0
  328. package/dist/side-nav/index.d.ts +2 -0
  329. package/dist/side-nav/index.js +2 -0
  330. package/dist/side-nav/side-nav.d.ts +72 -0
  331. package/dist/side-nav/side-nav.js +142 -0
  332. package/dist/side-nav/side-nav.js.map +1 -0
  333. package/dist/skeleton/skeleton.d.ts +8 -2
  334. package/dist/skeleton/skeleton.js +6 -2
  335. package/dist/skeleton/skeleton.js.map +1 -1
  336. package/dist/slider/index.d.ts +2 -2
  337. package/dist/slider/slider.d.ts +46 -14
  338. package/dist/slider/slider.js +188 -50
  339. package/dist/slider/slider.js.map +1 -1
  340. package/dist/slope-chart/index.d.ts +2 -0
  341. package/dist/slope-chart/index.js +2 -0
  342. package/dist/slope-chart/slope-chart.d.ts +54 -0
  343. package/dist/slope-chart/slope-chart.js +568 -0
  344. package/dist/slope-chart/slope-chart.js.map +1 -0
  345. package/dist/sparkline/index.d.ts +2 -0
  346. package/dist/sparkline/index.js +2 -0
  347. package/dist/sparkline/sparkline.d.ts +46 -0
  348. package/dist/sparkline/sparkline.js +390 -0
  349. package/dist/sparkline/sparkline.js.map +1 -0
  350. package/dist/split-bar/index.d.ts +2 -0
  351. package/dist/split-bar/index.js +2 -0
  352. package/dist/split-bar/split-bar.d.ts +62 -0
  353. package/dist/split-bar/split-bar.js +513 -0
  354. package/dist/split-bar/split-bar.js.map +1 -0
  355. package/dist/split-button/index.d.ts +2 -0
  356. package/dist/split-button/index.js +2 -0
  357. package/dist/split-button/split-button.d.ts +46 -0
  358. package/dist/split-button/split-button.js +123 -0
  359. package/dist/split-button/split-button.js.map +1 -0
  360. package/dist/stat-card/index.d.ts +2 -0
  361. package/dist/stat-card/index.js +2 -0
  362. package/dist/stat-card/stat-card.d.ts +101 -0
  363. package/dist/stat-card/stat-card.js +249 -0
  364. package/dist/stat-card/stat-card.js.map +1 -0
  365. package/dist/stepper/index.d.ts +2 -0
  366. package/dist/stepper/index.js +2 -0
  367. package/dist/stepper/stepper.d.ts +51 -0
  368. package/dist/stepper/stepper.js +215 -0
  369. package/dist/stepper/stepper.js.map +1 -0
  370. package/dist/streamgraph/index.d.ts +2 -0
  371. package/dist/streamgraph/index.js +2 -0
  372. package/dist/streamgraph/streamgraph.d.ts +70 -0
  373. package/dist/streamgraph/streamgraph.js +613 -0
  374. package/dist/streamgraph/streamgraph.js.map +1 -0
  375. package/dist/styles.css +1 -1
  376. package/dist/swipe-actions/index.d.ts +2 -0
  377. package/dist/swipe-actions/index.js +2 -0
  378. package/dist/swipe-actions/swipe-actions.d.ts +67 -0
  379. package/dist/swipe-actions/swipe-actions.js +552 -0
  380. package/dist/swipe-actions/swipe-actions.js.map +1 -0
  381. package/dist/switch/switch.js +10 -9
  382. package/dist/switch/switch.js.map +1 -1
  383. package/dist/table/index.d.ts +2 -2
  384. package/dist/table/index.js +2 -2
  385. package/dist/table/table.d.ts +87 -4
  386. package/dist/table/table.js +441 -165
  387. package/dist/table/table.js.map +1 -1
  388. package/dist/tabs/tabs.js +143 -7
  389. package/dist/tabs/tabs.js.map +1 -1
  390. package/dist/tag-input/index.d.ts +2 -0
  391. package/dist/tag-input/index.js +2 -0
  392. package/dist/tag-input/tag-input.d.ts +40 -0
  393. package/dist/tag-input/tag-input.js +269 -0
  394. package/dist/tag-input/tag-input.js.map +1 -0
  395. package/dist/text-morph/index.d.ts +2 -0
  396. package/dist/text-morph/index.js +2 -0
  397. package/dist/text-morph/text-morph.d.ts +23 -0
  398. package/dist/text-morph/text-morph.js +21 -0
  399. package/dist/text-morph/text-morph.js.map +1 -0
  400. package/dist/text-reveal/index.d.ts +2 -0
  401. package/dist/text-reveal/index.js +2 -0
  402. package/dist/text-reveal/text-reveal.d.ts +27 -0
  403. package/dist/text-reveal/text-reveal.js +51 -0
  404. package/dist/text-reveal/text-reveal.js.map +1 -0
  405. package/dist/text-shimmer/index.d.ts +2 -0
  406. package/dist/text-shimmer/index.js +2 -0
  407. package/dist/text-shimmer/text-shimmer.d.ts +29 -0
  408. package/dist/text-shimmer/text-shimmer.js +29 -0
  409. package/dist/text-shimmer/text-shimmer.js.map +1 -0
  410. package/dist/textarea/textarea.d.ts +23 -0
  411. package/dist/textarea/textarea.js +24 -2
  412. package/dist/textarea/textarea.js.map +1 -1
  413. package/dist/theme-switch/index.d.ts +2 -0
  414. package/dist/theme-switch/index.js +2 -0
  415. package/dist/theme-switch/theme-switch.d.ts +37 -0
  416. package/dist/theme-switch/theme-switch.js +123 -0
  417. package/dist/theme-switch/theme-switch.js.map +1 -0
  418. package/dist/time-picker/index.d.ts +2 -0
  419. package/dist/time-picker/index.js +2 -0
  420. package/dist/time-picker/time-picker.d.ts +54 -0
  421. package/dist/time-picker/time-picker.js +201 -0
  422. package/dist/time-picker/time-picker.js.map +1 -0
  423. package/dist/toast/index.d.ts +2 -2
  424. package/dist/toast/index.js +2 -2
  425. package/dist/toast/toast.d.ts +6 -0
  426. package/dist/toast/toast.js +98 -36
  427. package/dist/toast/toast.js.map +1 -1
  428. package/dist/tooltip/tooltip.d.ts +10 -3
  429. package/dist/tooltip/tooltip.js +67 -18
  430. package/dist/tooltip/tooltip.js.map +1 -1
  431. package/dist/treemap/index.d.ts +2 -0
  432. package/dist/treemap/index.js +2 -0
  433. package/dist/treemap/treemap.d.ts +53 -0
  434. package/dist/treemap/treemap.js +699 -0
  435. package/dist/treemap/treemap.js.map +1 -0
  436. package/dist/usage-meter/index.d.ts +2 -0
  437. package/dist/usage-meter/index.js +2 -0
  438. package/dist/usage-meter/usage-meter.d.ts +50 -0
  439. package/dist/usage-meter/usage-meter.js +440 -0
  440. package/dist/usage-meter/usage-meter.js.map +1 -0
  441. package/dist/waffle-chart/index.d.ts +2 -0
  442. package/dist/waffle-chart/index.js +2 -0
  443. package/dist/waffle-chart/waffle-chart.d.ts +57 -0
  444. package/dist/waffle-chart/waffle-chart.js +426 -0
  445. package/dist/waffle-chart/waffle-chart.js.map +1 -0
  446. package/package.json +245 -3
@@ -0,0 +1,219 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { mergeRefs } from "../lib/merge-refs.js";
4
+ import { prefersReducedMotion, useIsomorphicLayoutEffect } from "../lib/motion.js";
5
+ import { SwapText } from "../lib/swap-text.js";
6
+ import { MORPH, REVEAL, SMOOTH, live, retarget } from "../lib/spring-tween.js";
7
+ import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/gauge/gauge.tsx
10
+ /** A 270 degree ring open at the bottom, drawn clockwise from its lower left end. Redrawn from the sweep every frame so the round cap stays exact. */
11
+ const RADIUS = 42;
12
+ const START = -135;
13
+ const SPAN = 270;
14
+ const clamp = (value, low, high) => Math.min(high, Math.max(low, value));
15
+ function ringFor(sweep) {
16
+ const end = START + SPAN * clamp(sweep, 0, 1);
17
+ const at = (angle) => `${(50 + RADIUS * Math.sin(angle * Math.PI / 180)).toFixed(3)} ${(50 - RADIUS * Math.cos(angle * Math.PI / 180)).toFixed(3)}`;
18
+ return `M ${at(START)} A ${RADIUS} ${RADIUS} 0 ${end - START > 180 ? 1 : 0} 1 ${at(end)}`;
19
+ }
20
+ const TRACK = ringFor(1);
21
+ const Gauge = forwardRef(function Gauge({ value, min = 0, max = 100, label, detail, tone = "primary", thresholds, className, ...props }, ref) {
22
+ const safeMax = max > min ? max : min + 1;
23
+ const percentage = clamp((value - min) / (safeMax - min), 0, 1);
24
+ const displayValue = Math.round(percentage * 100);
25
+ const bands = [...thresholds ?? []].sort((a, b) => a.from - b.from);
26
+ const bandAt = (at) => bands.filter((band) => at >= band.from - 1e-6).pop();
27
+ const band = bandAt(value);
28
+ const figure = useRef(null);
29
+ const refs = useMemo(() => mergeRefs(ref, figure), [ref]);
30
+ const ring = useRef(null);
31
+ const digits = useRef(null);
32
+ const sizer = useRef(null);
33
+ const sweep = useRef(live(0));
34
+ const count = useRef(live(0));
35
+ const [seen, setSeen] = useState(false);
36
+ const [filled, setFilled] = useState(false);
37
+ const [shownBand, setShownBand] = useState(band);
38
+ const [moved, setMoved] = useState({
39
+ value: displayValue,
40
+ direction: 1
41
+ });
42
+ if (moved.value !== displayValue) setMoved({
43
+ value: displayValue,
44
+ direction: displayValue < moved.value ? -1 : 1
45
+ });
46
+ const latest = useRef({
47
+ bandAt,
48
+ min,
49
+ span: safeMax - min,
50
+ filled
51
+ });
52
+ useIsomorphicLayoutEffect(() => {
53
+ latest.current = {
54
+ bandAt,
55
+ min,
56
+ span: safeMax - min,
57
+ filled
58
+ };
59
+ });
60
+ const shownRef = useRef(shownBand);
61
+ useIsomorphicLayoutEffect(() => {
62
+ shownRef.current = shownBand;
63
+ });
64
+ /** One writer: the ring, its fade-in over the first sliver, and the count. */
65
+ const paint = useCallback(() => {
66
+ const to = clamp(sweep.current.value, 0, 1);
67
+ ring.current?.setAttribute("d", ringFor(to));
68
+ if (ring.current) ring.current.style.opacity = String(clamp(to / .02, 0, 1));
69
+ const shown = clamp(count.current.value, 0, 100);
70
+ if (digits.current) digits.current.textContent = String(Math.round(shown));
71
+ const { bandAt: pick, min: lo, span, filled: done } = latest.current;
72
+ if (done) {
73
+ const next = pick(lo + shown / 100 * span);
74
+ const current = shownRef.current;
75
+ if (next?.from !== current?.from || next?.label !== current?.label) {
76
+ shownRef.current = next;
77
+ setShownBand(next);
78
+ }
79
+ }
80
+ }, []);
81
+ useEffect(() => {
82
+ const node = figure.current;
83
+ if (!node || prefersReducedMotion() || typeof IntersectionObserver === "undefined") {
84
+ setSeen(true);
85
+ return;
86
+ }
87
+ const observer = new IntersectionObserver(([entry]) => {
88
+ if (!entry?.isIntersecting) return;
89
+ observer.disconnect();
90
+ setSeen(true);
91
+ }, { threshold: .5 });
92
+ observer.observe(node);
93
+ return () => observer.disconnect();
94
+ }, []);
95
+ const bandRef = useRef(band);
96
+ useIsomorphicLayoutEffect(() => {
97
+ bandRef.current = band;
98
+ });
99
+ useEffect(() => {
100
+ if (!seen) return;
101
+ const first = !latest.current.filled;
102
+ retarget(sweep.current, percentage, first ? REVEAL : MORPH, paint);
103
+ retarget(count.current, percentage * 100, first ? REVEAL : SMOOTH, paint, 0, first ? () => {
104
+ latest.current.filled = true;
105
+ shownRef.current = bandRef.current;
106
+ setShownBand(bandRef.current);
107
+ setFilled(true);
108
+ } : void 0);
109
+ }, [
110
+ percentage,
111
+ seen,
112
+ paint
113
+ ]);
114
+ useEffect(() => {
115
+ const sweeping = sweep.current;
116
+ const number = count.current;
117
+ return () => {
118
+ sweeping.stop();
119
+ number.stop();
120
+ };
121
+ }, []);
122
+ useIsomorphicLayoutEffect(paint, [paint]);
123
+ useEffect(() => {
124
+ const node = sizer.current;
125
+ const box = digits.current;
126
+ if (!node || !box || typeof ResizeObserver === "undefined") return;
127
+ const observer = new ResizeObserver(([entry]) => {
128
+ if (!entry) return;
129
+ box.style.width = `${entry.borderBoxSize?.[0]?.inlineSize ?? node.offsetWidth}px`;
130
+ });
131
+ observer.observe(node);
132
+ return () => observer.disconnect();
133
+ }, []);
134
+ const shown = filled ? shownBand : band;
135
+ const activeTone = (filled ? shownBand : band)?.tone ?? tone;
136
+ const clampedValue = clamp(value, min, safeMax);
137
+ return /* @__PURE__ */ jsxs("figure", {
138
+ ref: refs,
139
+ ...props,
140
+ "data-slot": "gauge",
141
+ "data-tone": activeTone,
142
+ className: cn("gauge", className),
143
+ children: [/* @__PURE__ */ jsxs("div", {
144
+ "data-slot": "gauge-visual",
145
+ role: "meter",
146
+ "aria-label": label,
147
+ "aria-valuemin": min,
148
+ "aria-valuemax": safeMax,
149
+ "aria-valuenow": clampedValue,
150
+ "aria-valuetext": `${displayValue}%${band ? `, ${band.label}` : ""}`,
151
+ className: "gauge-visual",
152
+ children: [/* @__PURE__ */ jsxs("svg", {
153
+ viewBox: "0 0 100 90",
154
+ "aria-hidden": "true",
155
+ focusable: "false",
156
+ className: "block size-full overflow-visible",
157
+ children: [/* @__PURE__ */ jsx("path", {
158
+ d: TRACK,
159
+ className: "gauge-track"
160
+ }), /* @__PURE__ */ jsx("path", {
161
+ ref: ring,
162
+ className: "gauge-fill",
163
+ style: { opacity: 0 }
164
+ })]
165
+ }), /* @__PURE__ */ jsxs("div", {
166
+ "aria-hidden": "true",
167
+ className: "gauge-readout",
168
+ children: [/* @__PURE__ */ jsxs("span", {
169
+ className: "gauge-number",
170
+ children: [
171
+ /* @__PURE__ */ jsx("span", {
172
+ ref: digits,
173
+ className: "gauge-digits"
174
+ }),
175
+ /* @__PURE__ */ jsx("span", {
176
+ className: "gauge-unit",
177
+ children: "%"
178
+ }),
179
+ /* @__PURE__ */ jsx("span", {
180
+ ref: sizer,
181
+ className: "gauge-sizer",
182
+ children: displayValue
183
+ })
184
+ ]
185
+ }), thresholds ? /* @__PURE__ */ jsx("span", {
186
+ className: "gauge-status",
187
+ children: /* @__PURE__ */ jsx(SwapText, {
188
+ swapKey: filled ? shown?.label ?? "" : "",
189
+ dir: moved.direction,
190
+ className: "block",
191
+ children: shown?.label
192
+ })
193
+ }) : null]
194
+ })]
195
+ }), /* @__PURE__ */ jsxs("figcaption", {
196
+ className: "grid min-w-0 gap-0.5",
197
+ children: [/* @__PURE__ */ jsx("strong", {
198
+ className: "text-sm font-medium text-foreground",
199
+ children: /* @__PURE__ */ jsx(SwapText, {
200
+ swapKey: label,
201
+ className: "block",
202
+ children: label
203
+ })
204
+ }), detail ? /* @__PURE__ */ jsx("span", {
205
+ className: "text-xs tabular-nums text-text-secondary",
206
+ children: /* @__PURE__ */ jsx(SwapText, {
207
+ swapKey: detail,
208
+ dir: moved.direction,
209
+ className: "block",
210
+ children: detail
211
+ })
212
+ }) : null]
213
+ })]
214
+ });
215
+ });
216
+ //#endregion
217
+ export { Gauge };
218
+
219
+ //# sourceMappingURL=gauge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gauge.js","names":[],"sources":["../../src/gauge/gauge.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n} from \"react\";\n\nimport { cn } from \"../lib/cn.js\";\nimport { mergeRefs } from \"../lib/merge-refs.js\";\nimport { prefersReducedMotion, useIsomorphicLayoutEffect } from \"../lib/motion.js\";\nimport { live, MORPH, retarget, REVEAL, SMOOTH } from \"../lib/spring-tween.js\";\nimport { SwapText } from \"../lib/swap-text.js\";\n\n/**\n * Gauge: one value against a range, as a ring open at the bottom with the\n * number at its centre. Use it for a score or a fill level; use Progress for a\n * task that finishes.\n *\n * The ring fills the first time it is seen, slowly and without overshoot, like\n * a ring closing. After that it springs to each new value with a little life\n * while the count follows without overshooting. A band that starts at\n * `from` sets the colour and names the state (\"Healthy\", \"At risk\"): the\n * highest band the value reaches wins, and it changes exactly as the count\n * crosses the threshold, so state never rests on colour alone. The label,\n * status and detail rise in when they change, from the side the value moved\n * toward.\n *\n * Plain SVG and CSS. One small spring tween writes the ring and the count\n * straight to the DOM. The ring is a `meter` for assistive technology.\n */\nexport type GaugeTone = \"primary\" | \"success\" | \"warning\" | \"danger\";\n\nexport interface GaugeThreshold {\n /** The band starts at this value (in the same unit as `value`). */\n from: number;\n tone: GaugeTone;\n /** Names the state. Shown under the number and announced with the value. */\n label: string;\n}\n\nexport interface GaugeProps extends Omit<ComponentPropsWithoutRef<\"figure\">, \"children\"> {\n value: number;\n /** @default 0 */\n min?: number;\n /** @default 100 */\n max?: number;\n /** What is measured. Names the meter. */\n label: string;\n /** A line under the label, such as \"Up 4 from last week\". */\n detail?: string;\n /** The colour when no band applies. @default \"primary\" */\n tone?: GaugeTone;\n /** Bands that set the tone and name the state. */\n thresholds?: GaugeThreshold[];\n}\n\n/** A 270 degree ring open at the bottom, drawn clockwise from its lower left end. Redrawn from the sweep every frame so the round cap stays exact. */\nconst RADIUS = 42;\nconst START = -135;\nconst SPAN = 270;\nconst clamp = (value: number, low: number, high: number) => Math.min(high, Math.max(low, value));\n\nfunction ringFor(sweep: number) {\n const end = START + SPAN * clamp(sweep, 0, 1);\n const at = (angle: number) =>\n `${(50 + RADIUS * Math.sin((angle * Math.PI) / 180)).toFixed(3)} ${(50 - RADIUS * Math.cos((angle * Math.PI) / 180)).toFixed(3)}`;\n return `M ${at(START)} A ${RADIUS} ${RADIUS} 0 ${end - START > 180 ? 1 : 0} 1 ${at(end)}`;\n}\nconst TRACK = ringFor(1);\n\nexport const Gauge = forwardRef<HTMLElement, GaugeProps>(function Gauge(\n { value, min = 0, max = 100, label, detail, tone = \"primary\", thresholds, className, ...props },\n ref,\n) {\n const safeMax = max > min ? max : min + 1;\n const percentage = clamp((value - min) / (safeMax - min), 0, 1);\n const displayValue = Math.round(percentage * 100);\n const bands = [...(thresholds ?? [])].sort((a, b) => a.from - b.from);\n const bandAt = (at: number) => bands.filter((band) => at >= band.from - 1e-6).pop();\n const band = bandAt(value);\n\n const figure = useRef<HTMLElement | null>(null);\n const refs = useMemo(() => mergeRefs(ref, figure), [ref]);\n const ring = useRef<SVGPathElement>(null);\n const digits = useRef<HTMLSpanElement>(null);\n const sizer = useRef<HTMLSpanElement>(null);\n const sweep = useRef(live(0));\n const count = useRef(live(0));\n\n const [seen, setSeen] = useState(false);\n const [filled, setFilled] = useState(false);\n // The band on screen: after the first fill it follows the number as it counts.\n const [shownBand, setShownBand] = useState(band);\n const [moved, setMoved] = useState({ value: displayValue, direction: 1 });\n if (moved.value !== displayValue) {\n setMoved({ value: displayValue, direction: displayValue < moved.value ? -1 : 1 });\n }\n\n const latest = useRef({ bandAt, min, span: safeMax - min, filled });\n useIsomorphicLayoutEffect(() => {\n latest.current = { bandAt, min, span: safeMax - min, filled };\n });\n const shownRef = useRef(shownBand);\n useIsomorphicLayoutEffect(() => {\n shownRef.current = shownBand;\n });\n\n /** One writer: the ring, its fade-in over the first sliver, and the count. */\n const paint = useCallback(() => {\n const to = clamp(sweep.current.value, 0, 1);\n ring.current?.setAttribute(\"d\", ringFor(to));\n if (ring.current) ring.current.style.opacity = String(clamp(to / 0.02, 0, 1));\n const shown = clamp(count.current.value, 0, 100);\n if (digits.current) digits.current.textContent = String(Math.round(shown));\n // After the first fill the state follows the number on screen, so the colour and label change as the count crosses a threshold.\n const { bandAt: pick, min: lo, span, filled: done } = latest.current;\n if (done) {\n const next = pick(lo + (shown / 100) * span);\n const current = shownRef.current;\n if (next?.from !== current?.from || next?.label !== current?.label) {\n shownRef.current = next;\n setShownBand(next);\n }\n }\n }, []);\n\n // The ring fills once half of it is in view.\n useEffect(() => {\n const node = figure.current;\n if (!node || prefersReducedMotion() || typeof IntersectionObserver === \"undefined\") {\n setSeen(true);\n return;\n }\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry?.isIntersecting) return;\n observer.disconnect();\n setSeen(true);\n },\n { threshold: 0.5 },\n );\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n // The first fill is slower and never overshoots; later values spring to place, the count a beat calmer.\n const bandRef = useRef(band);\n useIsomorphicLayoutEffect(() => {\n bandRef.current = band;\n });\n useEffect(() => {\n if (!seen) return;\n const first = !latest.current.filled;\n retarget(sweep.current, percentage, first ? REVEAL : MORPH, paint);\n retarget(\n count.current,\n percentage * 100,\n first ? REVEAL : SMOOTH,\n paint,\n 0,\n first\n ? () => {\n latest.current.filled = true;\n shownRef.current = bandRef.current;\n setShownBand(bandRef.current);\n setFilled(true);\n }\n : undefined,\n );\n }, [percentage, seen, paint]);\n useEffect(() => {\n const sweeping = sweep.current;\n const number = count.current;\n return () => {\n sweeping.stop();\n number.stop();\n };\n }, []);\n useIsomorphicLayoutEffect(paint, [paint]);\n\n // The digits sit right aligned in a box sized to the target number, so the ones column never jumps while counting and the group recentres when the number gains or loses a digit.\n useEffect(() => {\n const node = sizer.current;\n const box = digits.current;\n if (!node || !box || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(([entry]) => {\n if (!entry) return;\n box.style.width = `${entry.borderBoxSize?.[0]?.inlineSize ?? node.offsetWidth}px`;\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const shown = filled ? shownBand : band;\n const activeTone = (filled ? shownBand : band)?.tone ?? tone;\n const clampedValue = clamp(value, min, safeMax);\n\n return (\n <figure\n ref={refs}\n {...props}\n data-slot=\"gauge\"\n data-tone={activeTone}\n className={cn(\"gauge\", className)}\n >\n <div\n data-slot=\"gauge-visual\"\n role=\"meter\"\n aria-label={label}\n aria-valuemin={min}\n aria-valuemax={safeMax}\n aria-valuenow={clampedValue}\n aria-valuetext={`${displayValue}%${band ? `, ${band.label}` : \"\"}`}\n className=\"gauge-visual\"\n >\n <svg\n viewBox=\"0 0 100 90\"\n aria-hidden=\"true\"\n focusable=\"false\"\n className=\"block size-full overflow-visible\"\n >\n <path d={TRACK} className=\"gauge-track\" />\n <path ref={ring} className=\"gauge-fill\" style={{ opacity: 0 }} />\n </svg>\n <div aria-hidden=\"true\" className=\"gauge-readout\">\n <span className=\"gauge-number\">\n <span ref={digits} className=\"gauge-digits\" />\n <span className=\"gauge-unit\">%</span>\n <span ref={sizer} className=\"gauge-sizer\">\n {displayValue}\n </span>\n </span>\n {thresholds ? (\n <span className=\"gauge-status\">\n <SwapText\n swapKey={filled ? (shown?.label ?? \"\") : \"\"}\n dir={moved.direction}\n className=\"block\"\n >\n {shown?.label}\n </SwapText>\n </span>\n ) : null}\n </div>\n </div>\n <figcaption className=\"grid min-w-0 gap-0.5\">\n <strong className=\"text-sm font-medium text-foreground\">\n <SwapText swapKey={label} className=\"block\">\n {label}\n </SwapText>\n </strong>\n {detail ? (\n <span className=\"text-xs tabular-nums text-text-secondary\">\n <SwapText swapKey={detail} dir={moved.direction} className=\"block\">\n {detail}\n </SwapText>\n </span>\n ) : null}\n </figcaption>\n </figure>\n );\n});\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Gauge, GaugeProps, GaugeThreshold, GaugeTone } from "./gauge.js";
2
+ export { Gauge, type GaugeProps, type GaugeThreshold, type GaugeTone };
@@ -0,0 +1,2 @@
1
+ import { Gauge } from "./gauge.js";
2
+ export { Gauge };
@@ -0,0 +1,55 @@
1
+ import { SVGProps } from "react";
2
+ //#region src/icon-morph/icon-morph.d.ts
3
+ export type IconMorphName = "menu" | "play" | "plus" | "copy" | "theme" | "chevron" | "bell" | "heart";
4
+ export interface IconMorphIconProps extends Omit<SVGProps<SVGSVGElement>, "ref" | "children"> {
5
+ /**
6
+ * The second state of the icon. menu: close, play: pause, plus: check, copy: check,
7
+ * theme: moon, chevron: turned, bell: notifications on, heart: liked.
8
+ */
9
+ state?: boolean;
10
+ /** Rendered size in px. Defaults to 24. */
11
+ size?: number;
12
+ /** Stroke width in the 24 unit grid. Defaults to 1.75. */
13
+ strokeWidth?: number;
14
+ }
15
+ /**
16
+ * A family of icons that morph between two states instead of swapping. Lines
17
+ * rotate and slide into place, shapes interpolate their outlines, and a few
18
+ * carry a small moment of their own: the bell rings when it turns on and the
19
+ * heart bursts when liked. Every morph rides an interruptible spring, so
20
+ * toggling quickly reverses from wherever the icon is. The icons are
21
+ * decorative; put them inside a button that carries the accessible name and
22
+ * `aria-pressed`.
23
+ */
24
+ export interface IconMorphProps extends IconMorphIconProps {
25
+ name: IconMorphName;
26
+ }
27
+ /** Menu to close: the outer lines slide to the middle as they rotate into an X, and the middle line folds away. */
28
+ export declare function MenuIcon({ state, ...props }: IconMorphIconProps): import("react").JSX.Element;
29
+ /** Play to pause: the triangle splits into two halves that straighten into bars. */
30
+ export declare function PlayPauseIcon({ state, ...props }: IconMorphIconProps): import("react").JSX.Element;
31
+ /** Plus to check: each bar swings its ends to become one leg of the check. */
32
+ export declare function PlusCheckIcon({ state, ...props }: IconMorphIconProps): import("react").JSX.Element;
33
+ /** Copy to check: the back sheet tucks under the front one, the front one settles away, and the check draws in. */
34
+ export declare function CopyCheckIcon({ state, ...props }: IconMorphIconProps): import("react").JSX.Element;
35
+ /**
36
+ * Sun to moon: the disc grows while a shadow slides across it from the corner, carving the crescent, and the rays turn and fold in.
37
+ * The crescent is drawn as an outline: the disc's edge outside the shadow, and the shadow's edge inside the disc.
38
+ */
39
+ export declare function SunMoonIcon({ state, ...props }: IconMorphIconProps): import("react").JSX.Element;
40
+ export interface ChevronIconProps extends IconMorphIconProps {
41
+ /** Degrees the chevron turns when `state` is true. 180 flips down to up; 90 turns right to down. */
42
+ turn?: number;
43
+ /** Where the chevron points at rest. */
44
+ pointing?: "down" | "right";
45
+ }
46
+ /** A chevron that turns on a spring, for disclosure and sort controls. */
47
+ export declare function ChevronIcon({ state, turn, pointing, style, ...props }: ChevronIconProps): import("react").JSX.Element;
48
+ /** Notifications on and off: turning on rings the bell from its top, with the clapper lagging behind; turning off strikes it through. */
49
+ export declare function BellIcon({ state, ...props }: IconMorphIconProps): import("react").JSX.Element;
50
+ /** Like: the heart fills with a pop, and a ring and a few sparks burst out once. Unliking simply empties it. */
51
+ export declare function HeartIcon({ state, className, ...props }: IconMorphIconProps): import("react").JSX.Element;
52
+ /** One entry point for every morphing icon: pick it by `name` and drive it with `state`. */
53
+ export declare function IconMorph({ name, ...props }: IconMorphProps): import("react").JSX.Element;
54
+ //#endregion
55
+ //# sourceMappingURL=icon-morph.d.ts.map
@@ -0,0 +1,331 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { lerpPath, useSpringProgress } from "../lib/spring-progress.js";
4
+ import { useSvgId } from "../lib/svg-id.js";
5
+ import { useRef, useState } from "react";
6
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/icon-morph/icon-morph.tsx
8
+ /** Counts how many times `state` turned true after mount, so one-shot moments (a ring, a burst) replay on each turn on. */
9
+ function useTurnOns(state) {
10
+ const [previous, setPrevious] = useState(state);
11
+ const [count, setCount] = useState(0);
12
+ if (previous !== state) {
13
+ setPrevious(state);
14
+ if (state) setCount((value) => value + 1);
15
+ }
16
+ return count;
17
+ }
18
+ function Frame({ size = 24, strokeWidth = 1.75, state, className, children, ...rest }) {
19
+ return /* @__PURE__ */ jsx("svg", {
20
+ viewBox: "0 0 24 24",
21
+ width: size,
22
+ height: size,
23
+ fill: "none",
24
+ stroke: "currentColor",
25
+ strokeWidth,
26
+ strokeLinecap: "round",
27
+ strokeLinejoin: "round",
28
+ "aria-hidden": "true",
29
+ focusable: "false",
30
+ "data-on": state ? "" : void 0,
31
+ className: cn("block flex-none overflow-visible", className),
32
+ ...rest,
33
+ children
34
+ });
35
+ }
36
+ /** Menu to close: the outer lines slide to the middle as they rotate into an X, and the middle line folds away. */
37
+ function MenuIcon({ state = false, ...props }) {
38
+ return /* @__PURE__ */ jsxs(Frame, {
39
+ state,
40
+ ...props,
41
+ children: [
42
+ /* @__PURE__ */ jsx("path", {
43
+ d: "M4 6h16",
44
+ className: "icon-morph-menu-top"
45
+ }),
46
+ /* @__PURE__ */ jsx("path", {
47
+ d: "M4 12h16",
48
+ className: "icon-morph-menu-middle"
49
+ }),
50
+ /* @__PURE__ */ jsx("path", {
51
+ d: "M4 18h16",
52
+ className: "icon-morph-menu-bottom"
53
+ })
54
+ ]
55
+ });
56
+ }
57
+ const PLAY = ["M7 4.5 L12 7.42 L12 16.58 L7 19.5 Z", "M12 7.42 L19.5 11.8 L19.5 12.2 L12 16.58 Z"];
58
+ const PAUSE = ["M6.5 5 L10 5 L10 19 L6.5 19 Z", "M14 5 L17.5 5 L17.5 19 L14 19 Z"];
59
+ /**
60
+ * A pair of paths that morph between two outlines on the morph spring. The path
61
+ * is driven from script (see useSpringProgress): CSS cannot interpolate `d` in
62
+ * every browser.
63
+ */
64
+ function MorphPaths({ from, to, state, props }) {
65
+ const refs = useRef([]);
66
+ const [initial] = useState(() => from.map((d, i) => lerpPath(d, to[i], state ? 1 : 0)));
67
+ useSpringProgress(state ? 1 : 0, (progress) => {
68
+ refs.current.forEach((path, i) => path?.setAttribute("d", lerpPath(from[i], to[i], progress)));
69
+ });
70
+ return /* @__PURE__ */ jsx(Fragment$1, { children: from.map((_, i) => /* @__PURE__ */ jsx("path", {
71
+ ref: (node) => {
72
+ refs.current[i] = node;
73
+ },
74
+ d: initial[i],
75
+ ...props
76
+ }, i)) });
77
+ }
78
+ /** Play to pause: the triangle splits into two halves that straighten into bars. */
79
+ function PlayPauseIcon({ state = false, ...props }) {
80
+ return /* @__PURE__ */ jsx(Frame, {
81
+ state,
82
+ ...props,
83
+ children: /* @__PURE__ */ jsx(MorphPaths, {
84
+ from: PLAY,
85
+ to: PAUSE,
86
+ state,
87
+ props: {
88
+ fill: "currentColor",
89
+ strokeWidth: 1.5
90
+ }
91
+ })
92
+ });
93
+ }
94
+ /** Plus to check: each bar swings its ends to become one leg of the check. */
95
+ function PlusCheckIcon({ state = false, ...props }) {
96
+ return /* @__PURE__ */ jsx(Frame, {
97
+ state,
98
+ ...props,
99
+ children: /* @__PURE__ */ jsx(MorphPaths, {
100
+ from: ["M12 5 L12 19", "M5 12 L19 12"],
101
+ to: ["M20 6.5 L9.5 17", "M4.5 12 L9.5 17"],
102
+ state
103
+ })
104
+ });
105
+ }
106
+ /** Copy to check: the back sheet tucks under the front one, the front one settles away, and the check draws in. */
107
+ function CopyCheckIcon({ state = false, ...props }) {
108
+ return /* @__PURE__ */ jsxs(Frame, {
109
+ state,
110
+ ...props,
111
+ children: [
112
+ /* @__PURE__ */ jsx("path", {
113
+ d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",
114
+ className: "icon-morph-copy-back"
115
+ }),
116
+ /* @__PURE__ */ jsx("rect", {
117
+ x: "8",
118
+ y: "8",
119
+ width: "14",
120
+ height: "14",
121
+ rx: "2",
122
+ className: "icon-morph-copy-front"
123
+ }),
124
+ /* @__PURE__ */ jsx("path", {
125
+ d: "M5 12.5 L9.5 17 L19 7.5",
126
+ pathLength: 1,
127
+ className: "icon-morph-copy-check"
128
+ })
129
+ ]
130
+ });
131
+ }
132
+ const RAYS = Array.from({ length: 8 }, (_, index) => {
133
+ const angle = index * Math.PI / 4;
134
+ const c = Math.cos(angle);
135
+ const s = Math.sin(angle);
136
+ const r = (value) => Math.round(value * 100) / 100;
137
+ return "M" + r(12 + c * 7.5) + " " + r(12 + s * 7.5) + " L" + r(12 + c * 10) + " " + r(12 + s * 10);
138
+ });
139
+ /**
140
+ * Sun to moon: the disc grows while a shadow slides across it from the corner, carving the crescent, and the rays turn and fold in.
141
+ * The crescent is drawn as an outline: the disc's edge outside the shadow, and the shadow's edge inside the disc.
142
+ */
143
+ function SunMoonIcon({ state = false, ...props }) {
144
+ const id = useSvgId();
145
+ return /* @__PURE__ */ jsxs(Frame, {
146
+ state,
147
+ ...props,
148
+ children: [
149
+ /* @__PURE__ */ jsxs("defs", { children: [/* @__PURE__ */ jsxs("mask", {
150
+ id: id + "-bite",
151
+ maskUnits: "userSpaceOnUse",
152
+ x: "-8",
153
+ y: "-8",
154
+ width: "40",
155
+ height: "40",
156
+ children: [/* @__PURE__ */ jsx("rect", {
157
+ x: "-8",
158
+ y: "-8",
159
+ width: "40",
160
+ height: "40",
161
+ fill: "white",
162
+ stroke: "none"
163
+ }), /* @__PURE__ */ jsx("circle", {
164
+ cx: 30,
165
+ cy: -6,
166
+ r: 6.5,
167
+ fill: "black",
168
+ stroke: "none",
169
+ className: "icon-morph-sun-shadow"
170
+ })]
171
+ }), /* @__PURE__ */ jsx("clipPath", {
172
+ id: id + "-disc",
173
+ children: /* @__PURE__ */ jsx("circle", {
174
+ cx: 12,
175
+ cy: 12,
176
+ r: 4.5,
177
+ className: "icon-morph-sun-disc"
178
+ })
179
+ })] }),
180
+ /* @__PURE__ */ jsx("circle", {
181
+ cx: 12,
182
+ cy: 12,
183
+ r: 4.5,
184
+ mask: "url(#" + id + "-bite)",
185
+ className: "icon-morph-sun-disc"
186
+ }),
187
+ /* @__PURE__ */ jsx("circle", {
188
+ cx: 30,
189
+ cy: -6,
190
+ r: 6.5,
191
+ clipPath: "url(#" + id + "-disc)",
192
+ className: "icon-morph-sun-shadow"
193
+ }),
194
+ /* @__PURE__ */ jsx("g", {
195
+ className: "icon-morph-sun-rays",
196
+ children: RAYS.map((d) => /* @__PURE__ */ jsx("path", { d }, d))
197
+ })
198
+ ]
199
+ });
200
+ }
201
+ /** A chevron that turns on a spring, for disclosure and sort controls. */
202
+ function ChevronIcon({ state = false, turn = 180, pointing = "down", style, ...props }) {
203
+ return /* @__PURE__ */ jsx(Frame, {
204
+ state,
205
+ style: {
206
+ "--turn": turn + "deg",
207
+ ...style
208
+ },
209
+ ...props,
210
+ children: /* @__PURE__ */ jsx("path", {
211
+ d: pointing === "down" ? "M6 9 L12 15 L18 9" : "M9 6 L15 12 L9 18",
212
+ className: "icon-morph-chevron"
213
+ })
214
+ });
215
+ }
216
+ const BELL = "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9";
217
+ const CLAPPER = "M10.3 21a1.94 1.94 0 0 0 3.4 0";
218
+ /** Notifications on and off: turning on rings the bell from its top, with the clapper lagging behind; turning off strikes it through. */
219
+ function BellIcon({ state = false, ...props }) {
220
+ const id = useSvgId();
221
+ const rings = useTurnOns(state);
222
+ return /* @__PURE__ */ jsxs(Frame, {
223
+ state,
224
+ ...props,
225
+ children: [
226
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("mask", {
227
+ id: id + "-cut",
228
+ maskUnits: "userSpaceOnUse",
229
+ x: "-4",
230
+ y: "-4",
231
+ width: "32",
232
+ height: "32",
233
+ children: [/* @__PURE__ */ jsx("rect", {
234
+ x: "-4",
235
+ y: "-4",
236
+ width: "32",
237
+ height: "32",
238
+ fill: "white",
239
+ stroke: "none"
240
+ }), /* @__PURE__ */ jsx("path", {
241
+ d: "M3 3 L21 21",
242
+ stroke: "black",
243
+ strokeWidth: 5,
244
+ pathLength: 1,
245
+ className: "icon-morph-slash"
246
+ })]
247
+ }) }),
248
+ /* @__PURE__ */ jsxs("g", {
249
+ mask: "url(#" + id + "-cut)",
250
+ children: [/* @__PURE__ */ jsx("g", {
251
+ className: cn("[transform-box:fill-box] [transform-origin:50%_0%]", rings > 0 && "motion-safe:animate-bell-ring"),
252
+ children: /* @__PURE__ */ jsx("path", { d: BELL })
253
+ }, "bell-" + rings), /* @__PURE__ */ jsx("path", {
254
+ d: CLAPPER,
255
+ className: cn(rings > 0 && "motion-safe:animate-clapper-ring")
256
+ }, "clapper-" + rings)]
257
+ }),
258
+ /* @__PURE__ */ jsx("path", {
259
+ d: "M3 3 L21 21",
260
+ pathLength: 1,
261
+ className: "icon-morph-slash"
262
+ })
263
+ ]
264
+ });
265
+ }
266
+ const HEART = "M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z";
267
+ const SPARKS = Array.from({ length: 7 }, (_, index) => {
268
+ const angle = -Math.PI / 2 + index * 2 * Math.PI / 7;
269
+ return {
270
+ x: Math.cos(angle),
271
+ y: Math.sin(angle),
272
+ r: index % 2 ? 1 : 1.4
273
+ };
274
+ });
275
+ /** Like: the heart fills with a pop, and a ring and a few sparks burst out once. Unliking simply empties it. */
276
+ function HeartIcon({ state = false, className, ...props }) {
277
+ const likes = useTurnOns(state);
278
+ const burst = likes > 0 && state;
279
+ return /* @__PURE__ */ jsxs(Frame, {
280
+ state,
281
+ className: cn("icon-morph-heart", className),
282
+ ...props,
283
+ children: [burst ? /* @__PURE__ */ jsxs("g", {
284
+ stroke: "none",
285
+ children: [/* @__PURE__ */ jsx("circle", {
286
+ cx: 12,
287
+ cy: 12,
288
+ r: 13,
289
+ fill: "none",
290
+ stroke: "currentColor",
291
+ className: "motion-safe:animate-heart-ring"
292
+ }), SPARKS.map((spark, index) => /* @__PURE__ */ jsx("circle", {
293
+ cx: 12,
294
+ cy: 12,
295
+ r: spark.r,
296
+ fill: "currentColor",
297
+ style: {
298
+ "--sx": spark.x,
299
+ "--sy": spark.y
300
+ },
301
+ className: "icon-morph-part motion-safe:animate-heart-spark"
302
+ }, index))]
303
+ }, "burst-" + likes) : null, /* @__PURE__ */ jsx("g", {
304
+ className: cn("icon-morph-part", burst && "motion-safe:animate-heart-pop"),
305
+ children: /* @__PURE__ */ jsx("path", {
306
+ d: HEART,
307
+ fill: "currentColor",
308
+ className: "icon-morph-heart-fill"
309
+ })
310
+ }, "heart-" + likes)]
311
+ });
312
+ }
313
+ const ICONS = {
314
+ menu: MenuIcon,
315
+ play: PlayPauseIcon,
316
+ plus: PlusCheckIcon,
317
+ copy: CopyCheckIcon,
318
+ theme: SunMoonIcon,
319
+ chevron: ChevronIcon,
320
+ bell: BellIcon,
321
+ heart: HeartIcon
322
+ };
323
+ /** One entry point for every morphing icon: pick it by `name` and drive it with `state`. */
324
+ function IconMorph({ name, ...props }) {
325
+ const Icon = ICONS[name];
326
+ return /* @__PURE__ */ jsx(Icon, { ...props });
327
+ }
328
+ //#endregion
329
+ export { BellIcon, ChevronIcon, CopyCheckIcon, HeartIcon, IconMorph, MenuIcon, PlayPauseIcon, PlusCheckIcon, SunMoonIcon };
330
+
331
+ //# sourceMappingURL=icon-morph.js.map