@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
@@ -0,0 +1,577 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { mergeRefs } from "../lib/merge-refs.js";
4
+ import { ActionButton } from "../action-button/action-button.js";
5
+ import { SwapText } from "../lib/swap-text.js";
6
+ import { RollingNumber } from "../lib/field-message.js";
7
+ import { forwardRef, useEffect, useId, useMemo, useReducer, useRef, useState } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/onboarding-checklist/onboarding-checklist.tsx
10
+ /** How long a checked step stays in place, struck through, before it folds into the completed row. */
11
+ const SETTLE_MS = 720;
12
+ const ordered = (ids, steps) => steps.map((step) => step.id).filter((id) => ids.includes(id));
13
+ const without = (ids, id) => ids.filter((item) => item !== id);
14
+ const omit = (errors, id) => Object.fromEntries(Object.entries(errors).filter(([key]) => key !== id));
15
+ const titleOf = (steps, id) => steps.find((step) => step.id === id)?.title ?? "Step";
16
+ function init({ steps, completed, hidden }) {
17
+ const done = ordered(completed, steps);
18
+ return {
19
+ done,
20
+ settled: done,
21
+ expanded: steps.find((step) => !done.includes(step.id))?.id ?? null,
22
+ errors: {},
23
+ groupOpen: false,
24
+ hidden,
25
+ message: ""
26
+ };
27
+ }
28
+ function reducer(state, action) {
29
+ switch (action.type) {
30
+ case "check": {
31
+ if (state.done.includes(action.id)) return state;
32
+ const done = ordered([...state.done, action.id], action.steps);
33
+ const total = action.steps.length;
34
+ return {
35
+ ...state,
36
+ done,
37
+ errors: omit(state.errors, action.id),
38
+ message: done.length === total ? `All ${total} steps done.` : `${titleOf(action.steps, action.id)} done. ${done.length} of ${total} complete.`
39
+ };
40
+ }
41
+ case "uncheck": {
42
+ if (!state.done.includes(action.id)) return state;
43
+ const done = without(state.done, action.id);
44
+ return {
45
+ ...state,
46
+ done,
47
+ settled: without(state.settled, action.id),
48
+ expanded: state.expanded ?? action.id,
49
+ message: `${titleOf(action.steps, action.id)} marked as not done. ${done.length} of ${action.steps.length} complete.`
50
+ };
51
+ }
52
+ case "settle": {
53
+ if (!state.done.includes(action.id) || state.settled.includes(action.id)) return state;
54
+ let expanded = state.expanded;
55
+ if (expanded === action.id) {
56
+ const order = action.steps.map((step) => step.id);
57
+ const start = order.indexOf(action.id);
58
+ expanded = order.map((_, offset) => order[(start + offset + 1) % order.length]).find((id) => !state.done.includes(id)) ?? null;
59
+ }
60
+ return {
61
+ ...state,
62
+ settled: ordered([...state.settled, action.id], action.steps),
63
+ expanded
64
+ };
65
+ }
66
+ case "expand": return {
67
+ ...state,
68
+ expanded: state.expanded === action.id ? null : action.id
69
+ };
70
+ case "start": return {
71
+ ...state,
72
+ errors: omit(state.errors, action.id)
73
+ };
74
+ case "fail": return {
75
+ ...state,
76
+ errors: {
77
+ ...state.errors,
78
+ [action.id]: action.message
79
+ },
80
+ message: action.message
81
+ };
82
+ case "group": return {
83
+ ...state,
84
+ groupOpen: !state.groupOpen
85
+ };
86
+ case "hide": return {
87
+ ...state,
88
+ hidden: !state.hidden
89
+ };
90
+ }
91
+ }
92
+ const Chevron = () => /* @__PURE__ */ jsx("svg", {
93
+ width: 16,
94
+ height: 16,
95
+ viewBox: "0 0 24 24",
96
+ fill: "none",
97
+ stroke: "currentColor",
98
+ strokeWidth: 1.75,
99
+ strokeLinecap: "round",
100
+ strokeLinejoin: "round",
101
+ "aria-hidden": "true",
102
+ children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" })
103
+ });
104
+ /**
105
+ * A box that opens and closes its height (a grid track going between 0fr and 1fr).
106
+ * Closed, it is visibility: hidden once folded, so it leaves the tab order.
107
+ */
108
+ function Collapse({ show, children }) {
109
+ return /* @__PURE__ */ jsx("div", {
110
+ "data-shown": show || void 0,
111
+ className: "checklist-collapse",
112
+ children: /* @__PURE__ */ jsx("div", { children })
113
+ });
114
+ }
115
+ /** Every label the slot can show sits invisibly underneath, so a swap never changes the slot's size. */
116
+ function SwapLabel({ text, options }) {
117
+ return /* @__PURE__ */ jsxs("span", {
118
+ className: "checklist-swap",
119
+ "aria-hidden": "true",
120
+ children: [options.map((option, index) => /* @__PURE__ */ jsx("span", {
121
+ className: "checklist-swap-sizer",
122
+ children: option
123
+ }, index)), /* @__PURE__ */ jsx(SwapText, {
124
+ swapKey: text,
125
+ motion: "rise",
126
+ className: "checklist-swap-item",
127
+ children: text
128
+ })]
129
+ });
130
+ }
131
+ /** The ring's stroke fills on a spring as steps are checked; once every step is done a tick draws in its center. */
132
+ function ProgressRing({ done, total }) {
133
+ const ratio = total ? done / total : 0;
134
+ const complete = total > 0 && done === total;
135
+ return /* @__PURE__ */ jsxs("span", {
136
+ className: "checklist-ring",
137
+ role: "progressbar",
138
+ "aria-label": "Setup progress",
139
+ "aria-valuemin": 0,
140
+ "aria-valuemax": total,
141
+ "aria-valuenow": done,
142
+ "aria-valuetext": `${done} of ${total} steps done`,
143
+ children: [/* @__PURE__ */ jsxs("svg", {
144
+ viewBox: "0 0 40 40",
145
+ fill: "none",
146
+ "aria-hidden": "true",
147
+ children: [/* @__PURE__ */ jsx("circle", {
148
+ className: "checklist-ring-track",
149
+ cx: "20",
150
+ cy: "20",
151
+ r: "17",
152
+ strokeWidth: 3
153
+ }), /* @__PURE__ */ jsx("g", {
154
+ transform: "rotate(-90 20 20)",
155
+ children: /* @__PURE__ */ jsx("circle", {
156
+ className: "checklist-ring-fill",
157
+ cx: "20",
158
+ cy: "20",
159
+ r: "17",
160
+ strokeWidth: 3,
161
+ strokeLinecap: "round",
162
+ pathLength: 1,
163
+ "data-started": ratio > 0 ? "" : void 0,
164
+ style: { "--ratio": ratio }
165
+ })
166
+ })]
167
+ }), /* @__PURE__ */ jsx("span", {
168
+ className: "checklist-ring-tick",
169
+ "aria-hidden": "true",
170
+ children: /* @__PURE__ */ jsx(SwapText, {
171
+ swapKey: complete ? "tick" : "",
172
+ motion: "glyph",
173
+ className: "grid place-items-center",
174
+ children: complete ? /* @__PURE__ */ jsx("svg", {
175
+ viewBox: "0 0 40 40",
176
+ fill: "none",
177
+ children: /* @__PURE__ */ jsx("path", {
178
+ className: "checklist-draw",
179
+ pathLength: 1,
180
+ d: "M13.5 20.5 18 25l8.5-9.5",
181
+ stroke: "currentColor",
182
+ strokeWidth: 2.25,
183
+ strokeLinecap: "round",
184
+ strokeLinejoin: "round"
185
+ })
186
+ }) : null
187
+ })
188
+ })]
189
+ });
190
+ }
191
+ /** The fill grows from the center while the tick draws from its short stroke; unchecking retracts both quickly. */
192
+ function CheckButton({ checked, labelledBy, onToggle }) {
193
+ return /* @__PURE__ */ jsx("button", {
194
+ type: "button",
195
+ role: "checkbox",
196
+ "aria-checked": checked,
197
+ "aria-labelledby": labelledBy,
198
+ className: "checklist-check",
199
+ "data-check": "",
200
+ onClick: onToggle,
201
+ children: /* @__PURE__ */ jsxs("span", {
202
+ className: "checklist-check-visual",
203
+ "aria-hidden": "true",
204
+ children: [/* @__PURE__ */ jsx("span", { className: "checklist-check-fill" }), /* @__PURE__ */ jsx("svg", {
205
+ className: "checklist-check-mark",
206
+ viewBox: "0 0 22 22",
207
+ fill: "none",
208
+ children: /* @__PURE__ */ jsx("path", {
209
+ pathLength: 1,
210
+ d: "M6.75 11.25 9.75 14.25 15.25 8.25",
211
+ stroke: "currentColor",
212
+ strokeWidth: 1.75,
213
+ strokeLinecap: "round",
214
+ strokeLinejoin: "round"
215
+ })
216
+ })]
217
+ })
218
+ });
219
+ }
220
+ function StepItem({ step, baseId, done, settled, expanded, error, onToggle, onExpand, onRun }) {
221
+ const titleId = `${baseId}-${step.id}-title`;
222
+ const panelId = `${baseId}-${step.id}-panel`;
223
+ const [lastError, setLastError] = useState(error);
224
+ if (error && error !== lastError) setLastError(error);
225
+ return /* @__PURE__ */ jsx("li", {
226
+ "data-step": step.id,
227
+ "data-done": done || void 0,
228
+ "data-current": expanded || void 0,
229
+ "data-open": settled ? void 0 : "",
230
+ children: /* @__PURE__ */ jsx(Collapse, {
231
+ show: !settled,
232
+ children: /* @__PURE__ */ jsxs("div", {
233
+ className: "checklist-step-inner",
234
+ children: [/* @__PURE__ */ jsx(CheckButton, {
235
+ checked: done,
236
+ labelledBy: titleId,
237
+ onToggle
238
+ }), /* @__PURE__ */ jsxs("div", {
239
+ className: "checklist-step-main",
240
+ children: [/* @__PURE__ */ jsx("button", {
241
+ type: "button",
242
+ className: "checklist-step-title",
243
+ "data-title": "",
244
+ "aria-expanded": expanded,
245
+ "aria-controls": panelId,
246
+ onClick: onExpand,
247
+ children: /* @__PURE__ */ jsx("span", {
248
+ id: titleId,
249
+ className: "checklist-title-text",
250
+ children: step.title
251
+ })
252
+ }), /* @__PURE__ */ jsx(Collapse, {
253
+ show: expanded,
254
+ children: /* @__PURE__ */ jsxs("div", {
255
+ id: panelId,
256
+ role: "region",
257
+ "aria-labelledby": titleId,
258
+ className: "checklist-panel-inner",
259
+ children: [
260
+ step.description ? /* @__PURE__ */ jsx("p", {
261
+ className: "checklist-description",
262
+ children: step.description
263
+ }) : null,
264
+ /* @__PURE__ */ jsx(Collapse, {
265
+ show: Boolean(error),
266
+ children: /* @__PURE__ */ jsx("p", {
267
+ role: "alert",
268
+ className: "checklist-error",
269
+ children: lastError
270
+ })
271
+ }),
272
+ step.actionLabel ? /* @__PURE__ */ jsx(ActionButton, {
273
+ variant: "primary",
274
+ size: "sm",
275
+ className: "mt-3",
276
+ "data-primary": "",
277
+ pendingLabel: step.actionLabel,
278
+ successLabel: step.actionLabel,
279
+ onAction: onRun,
280
+ children: step.actionLabel
281
+ }) : null
282
+ ]
283
+ })
284
+ })]
285
+ })]
286
+ })
287
+ })
288
+ });
289
+ }
290
+ const OnboardingChecklist = forwardRef(function OnboardingChecklist({ title, doneTitle = "You’re all set", steps, defaultCompleted = [], onCompletedChange, defaultHidden = false, onHiddenChange, className }, ref) {
291
+ const baseId = useId();
292
+ const [state, dispatch] = useReducer(reducer, {
293
+ steps,
294
+ completed: defaultCompleted,
295
+ hidden: defaultHidden
296
+ }, init);
297
+ const root = useRef(null);
298
+ const refs = useMemo(() => mergeRefs(ref, root), [ref]);
299
+ const timers = useRef(/* @__PURE__ */ new Map());
300
+ const focusRequest = useRef(null);
301
+ const reportCompleted = useRef(onCompletedChange);
302
+ const reported = useRef(state.done);
303
+ useEffect(() => {
304
+ reportCompleted.current = onCompletedChange;
305
+ });
306
+ useEffect(() => {
307
+ if (reported.current === state.done) return;
308
+ reported.current = state.done;
309
+ reportCompleted.current?.(state.done);
310
+ }, [state.done]);
311
+ useEffect(() => {
312
+ const pending = timers.current;
313
+ return () => pending.forEach(clearTimeout);
314
+ }, []);
315
+ useEffect(() => {
316
+ const request = focusRequest.current;
317
+ const node = root.current;
318
+ if (!request || !node) return;
319
+ focusRequest.current = null;
320
+ let target;
321
+ if (request === "next") {
322
+ const next = state.expanded ? node.querySelector(`[data-step="${state.expanded}"][data-open]`) : null;
323
+ target = next?.querySelector("[data-primary]") ?? next?.querySelector("[data-title]") ?? node.querySelector("[data-group-toggle]");
324
+ } else target = node.querySelector(`[data-step="${request.id}"][data-open] [data-check]`);
325
+ target?.focus({ preventScroll: true });
326
+ });
327
+ function check(id) {
328
+ dispatch({
329
+ type: "check",
330
+ id,
331
+ steps
332
+ });
333
+ if (timers.current.has(id)) return;
334
+ timers.current.set(id, setTimeout(() => {
335
+ timers.current.delete(id);
336
+ if (root.current?.querySelector(`[data-step="${id}"]`)?.contains(document.activeElement)) focusRequest.current = "next";
337
+ dispatch({
338
+ type: "settle",
339
+ id,
340
+ steps
341
+ });
342
+ }, SETTLE_MS));
343
+ }
344
+ function uncheck(id, fromGroup) {
345
+ clearTimeout(timers.current.get(id));
346
+ timers.current.delete(id);
347
+ if (fromGroup) focusRequest.current = { id };
348
+ dispatch({
349
+ type: "uncheck",
350
+ id,
351
+ steps
352
+ });
353
+ }
354
+ async function run(step) {
355
+ if (!step.onAction || state.done.includes(step.id)) return;
356
+ dispatch({
357
+ type: "start",
358
+ id: step.id,
359
+ steps
360
+ });
361
+ try {
362
+ await step.onAction();
363
+ } catch (error) {
364
+ dispatch({
365
+ type: "fail",
366
+ id: step.id,
367
+ message: error instanceof Error && error.message ? error.message : "That didn’t work. Try again."
368
+ });
369
+ throw error;
370
+ }
371
+ check(step.id);
372
+ }
373
+ function toggleHidden() {
374
+ dispatch({ type: "hide" });
375
+ onHiddenChange?.(!state.hidden);
376
+ }
377
+ /** Up and Down walk the step titles, Home and End jump to the first and last. */
378
+ function navigate(event) {
379
+ const target = event.target;
380
+ if (!target.matches("[data-title]") || ![
381
+ "ArrowDown",
382
+ "ArrowUp",
383
+ "Home",
384
+ "End"
385
+ ].includes(event.key)) return;
386
+ const titles = Array.from(event.currentTarget.querySelectorAll("li[data-open] [data-title]"));
387
+ const index = titles.indexOf(target);
388
+ const next = event.key === "Home" ? 0 : event.key === "End" ? titles.length - 1 : (index + (event.key === "ArrowDown" ? 1 : -1) + titles.length) % titles.length;
389
+ event.preventDefault();
390
+ titles[next]?.focus();
391
+ }
392
+ const total = steps.length;
393
+ const doneCount = state.done.length;
394
+ const allDone = total > 0 && doneCount === total;
395
+ const completed = steps.filter((step) => state.settled.includes(step.id));
396
+ const titleId = `${baseId}-title`;
397
+ const bodyId = `${baseId}-body`;
398
+ const groupId = `${baseId}-completed`;
399
+ return /* @__PURE__ */ jsxs("section", {
400
+ ref: refs,
401
+ "aria-labelledby": titleId,
402
+ "data-slot": "onboarding-checklist",
403
+ "data-complete": allDone || void 0,
404
+ "data-hidden": state.hidden || void 0,
405
+ className: cn("checklist box-border font-sans", className),
406
+ children: [
407
+ /* @__PURE__ */ jsxs("div", {
408
+ className: "checklist-header",
409
+ children: [
410
+ /* @__PURE__ */ jsx(ProgressRing, {
411
+ done: doneCount,
412
+ total
413
+ }),
414
+ /* @__PURE__ */ jsxs("div", {
415
+ className: "checklist-heading",
416
+ children: [/* @__PURE__ */ jsxs("h3", {
417
+ id: titleId,
418
+ className: "checklist-title",
419
+ children: [/* @__PURE__ */ jsx("span", {
420
+ className: "sr-only",
421
+ children: allDone ? doneTitle : title
422
+ }), /* @__PURE__ */ jsx(SwapLabel, {
423
+ text: allDone ? doneTitle : title,
424
+ options: [title, doneTitle]
425
+ })]
426
+ }), /* @__PURE__ */ jsxs("p", {
427
+ className: "checklist-count",
428
+ children: [/* @__PURE__ */ jsxs("span", {
429
+ className: "sr-only",
430
+ children: [
431
+ doneCount,
432
+ " of ",
433
+ total,
434
+ " done"
435
+ ]
436
+ }), /* @__PURE__ */ jsxs("span", {
437
+ className: "checklist-count-visual",
438
+ "aria-hidden": "true",
439
+ children: [
440
+ /* @__PURE__ */ jsx(RollingNumber, { word: String(doneCount) }),
441
+ "\xA0of ",
442
+ total,
443
+ " done"
444
+ ]
445
+ })]
446
+ })]
447
+ }),
448
+ /* @__PURE__ */ jsxs("button", {
449
+ type: "button",
450
+ className: "checklist-hide",
451
+ "aria-expanded": !state.hidden,
452
+ "aria-controls": bodyId,
453
+ onClick: toggleHidden,
454
+ children: [
455
+ /* @__PURE__ */ jsx("span", {
456
+ className: "checklist-hide-label",
457
+ children: /* @__PURE__ */ jsx(SwapLabel, {
458
+ text: state.hidden ? "Show" : "Hide",
459
+ options: ["Hide", "Show"]
460
+ })
461
+ }),
462
+ /* @__PURE__ */ jsxs("span", {
463
+ className: "sr-only",
464
+ children: [state.hidden ? "Show" : "Hide", " checklist"]
465
+ }),
466
+ /* @__PURE__ */ jsx("span", {
467
+ className: "checklist-chevron",
468
+ "aria-hidden": "true",
469
+ "data-flipped": state.hidden || void 0,
470
+ children: /* @__PURE__ */ jsx(Chevron, {})
471
+ })
472
+ ]
473
+ })
474
+ ]
475
+ }),
476
+ /* @__PURE__ */ jsx("div", {
477
+ id: bodyId,
478
+ "data-shown": state.hidden ? void 0 : "",
479
+ className: "checklist-collapse",
480
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("div", {
481
+ className: "checklist-body-inner",
482
+ children: [/* @__PURE__ */ jsx("ul", {
483
+ className: "checklist-list",
484
+ "aria-label": "Steps to do",
485
+ "aria-hidden": completed.length === total ? true : void 0,
486
+ onKeyDown: navigate,
487
+ children: steps.map((step) => /* @__PURE__ */ jsx(StepItem, {
488
+ step,
489
+ baseId,
490
+ done: state.done.includes(step.id),
491
+ settled: state.settled.includes(step.id),
492
+ expanded: state.expanded === step.id,
493
+ error: state.errors[step.id],
494
+ onToggle: () => state.done.includes(step.id) ? uncheck(step.id, false) : check(step.id),
495
+ onExpand: () => dispatch({
496
+ type: "expand",
497
+ id: step.id,
498
+ steps
499
+ }),
500
+ onRun: () => run(step)
501
+ }, step.id))
502
+ }), /* @__PURE__ */ jsxs(Collapse, {
503
+ show: completed.length > 0,
504
+ children: [/* @__PURE__ */ jsxs("button", {
505
+ type: "button",
506
+ className: "checklist-group-toggle",
507
+ "data-group-toggle": "",
508
+ "aria-expanded": state.groupOpen,
509
+ "aria-controls": groupId,
510
+ onClick: () => dispatch({ type: "group" }),
511
+ children: [
512
+ /* @__PURE__ */ jsxs("span", {
513
+ className: "sr-only",
514
+ children: [completed.length, " completed"]
515
+ }),
516
+ /* @__PURE__ */ jsxs("span", {
517
+ className: "checklist-count-visual",
518
+ "aria-hidden": "true",
519
+ children: [/* @__PURE__ */ jsx(RollingNumber, { word: String(completed.length) }), "\xA0completed"]
520
+ }),
521
+ /* @__PURE__ */ jsx("span", {
522
+ className: "checklist-chevron",
523
+ "aria-hidden": "true",
524
+ "data-flipped": state.groupOpen ? void 0 : "",
525
+ children: /* @__PURE__ */ jsx(Chevron, {})
526
+ })
527
+ ]
528
+ }), /* @__PURE__ */ jsx(Collapse, {
529
+ show: state.groupOpen,
530
+ children: /* @__PURE__ */ jsx("div", {
531
+ id: groupId,
532
+ children: /* @__PURE__ */ jsx("ul", {
533
+ className: "checklist-list",
534
+ "aria-label": "Completed steps",
535
+ children: steps.map((step) => {
536
+ const doneId = `${baseId}-${step.id}-done`;
537
+ return /* @__PURE__ */ jsx("li", {
538
+ "data-completed-step": step.id,
539
+ "data-done": "",
540
+ children: /* @__PURE__ */ jsx(Collapse, {
541
+ show: state.settled.includes(step.id),
542
+ children: /* @__PURE__ */ jsxs("div", {
543
+ className: "checklist-step-inner",
544
+ children: [/* @__PURE__ */ jsx(CheckButton, {
545
+ checked: true,
546
+ labelledBy: doneId,
547
+ onToggle: () => uncheck(step.id, true)
548
+ }), /* @__PURE__ */ jsx("span", {
549
+ className: "checklist-done-title",
550
+ children: /* @__PURE__ */ jsx("span", {
551
+ id: doneId,
552
+ className: "checklist-title-text",
553
+ children: step.title
554
+ })
555
+ })]
556
+ })
557
+ })
558
+ }, step.id);
559
+ })
560
+ })
561
+ })
562
+ })]
563
+ })]
564
+ }) })
565
+ }),
566
+ /* @__PURE__ */ jsx("span", {
567
+ className: "sr-only",
568
+ role: "status",
569
+ children: state.message
570
+ })
571
+ ]
572
+ });
573
+ });
574
+ //#endregion
575
+ export { OnboardingChecklist };
576
+
577
+ //# sourceMappingURL=onboarding-checklist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding-checklist.js","names":[],"sources":["../../src/onboarding-checklist/onboarding-checklist.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useReducer,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\n\nimport { ActionButton } from \"../action-button/action-button.js\";\nimport { cn } from \"../lib/cn.js\";\nimport { RollingNumber } from \"../lib/field-message.js\";\nimport { mergeRefs } from \"../lib/merge-refs.js\";\nimport { SwapText } from \"../lib/swap-text.js\";\n\n/**\n * OnboardingChecklist: a getting-started card for a new account or workspace,\n * for a short, one-time setup of three to eight loosely ordered steps. (Use a\n * Stepper when the order is strict and steps map to screens.)\n *\n * The progress ring and the count follow every check: the ring fills on the\n * morph spring, the count rolls its digits, and at 100% a tick draws in the\n * ring while the title morphs to `doneTitle`. A checked step fills its circle\n * from the centre, draws its tick and strikes its title through; 720ms later it\n * folds into a \"N completed\" row that opens again, and the next unfinished step\n * opens and takes focus if the finished one had it. A step with an `actionLabel`\n * runs `onAction`: resolving checks the step, throwing an Error keeps it open\n * and shows the message. The body can be hidden and shown again.\n *\n * Rows and panels open and close their height on a spring that never\n * overshoots, closing a little quicker. Nothing animates on first render, and\n * reduced motion removes the height animation and keeps short fades.\n *\n * Built on plain buttons and the shared swap and rolling-number helpers; the\n * action is the library's ActionButton, whose arrow becomes a spinner and then\n * a tick that draws itself. Keyboard: Up and Down walk the step titles,\n * Home and End jump to the first and last, Enter or Space expands a step,\n * toggles its checkbox or runs its action.\n */\nexport interface OnboardingStep {\n id: string;\n title: string;\n description?: string;\n /** Label of the button that does the step. Without it, the step is checked off by hand. */\n actionLabel?: string;\n /** Runs the step. Resolve to check it off; throw an Error to keep it open and show the error's message. */\n onAction?: () => void | Promise<void>;\n}\n\nexport interface OnboardingChecklistProps {\n /** Card title while steps remain. */\n title: string;\n /** Title once every step is done. @default \"You’re all set\" */\n doneTitle?: string;\n /** Steps in order. */\n steps: OnboardingStep[];\n /** Step ids that start completed. */\n defaultCompleted?: string[];\n /** Called with the completed ids, in step order, whenever they change. */\n onCompletedChange?: (completed: string[]) => void;\n /** Starts with the body collapsed. @default false */\n defaultHidden?: boolean;\n /** Called when the Hide or Show button is used. */\n onHiddenChange?: (hidden: boolean) => void;\n /** Extra classes for the card. Merged last. */\n className?: string;\n}\n\ninterface State {\n done: string[];\n settled: string[];\n expanded: string | null;\n errors: Record<string, string>;\n groupOpen: boolean;\n hidden: boolean;\n message: string;\n}\ntype Action =\n | { type: \"check\" | \"uncheck\" | \"settle\" | \"expand\" | \"start\"; id: string; steps: OnboardingStep[] }\n | { type: \"fail\"; id: string; message: string }\n | { type: \"group\" | \"hide\" };\n\n/** How long a checked step stays in place, struck through, before it folds into the completed row. */\nconst SETTLE_MS = 720;\n\nconst ordered = (ids: string[], steps: OnboardingStep[]) =>\n steps.map((step) => step.id).filter((id) => ids.includes(id));\nconst without = (ids: string[], id: string) => ids.filter((item) => item !== id);\nconst omit = (errors: Record<string, string>, id: string) =>\n Object.fromEntries(Object.entries(errors).filter(([key]) => key !== id));\nconst titleOf = (steps: OnboardingStep[], id: string) =>\n steps.find((step) => step.id === id)?.title ?? \"Step\";\n\nfunction init({\n steps,\n completed,\n hidden,\n}: {\n steps: OnboardingStep[];\n completed: string[];\n hidden: boolean;\n}): State {\n const done = ordered(completed, steps);\n return {\n done,\n settled: done,\n expanded: steps.find((step) => !done.includes(step.id))?.id ?? null,\n errors: {},\n groupOpen: false,\n hidden,\n message: \"\",\n };\n}\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case \"check\": {\n if (state.done.includes(action.id)) return state;\n const done = ordered([...state.done, action.id], action.steps);\n const total = action.steps.length;\n return {\n ...state,\n done,\n errors: omit(state.errors, action.id),\n message:\n done.length === total\n ? `All ${total} steps done.`\n : `${titleOf(action.steps, action.id)} done. ${done.length} of ${total} complete.`,\n };\n }\n case \"uncheck\": {\n if (!state.done.includes(action.id)) return state;\n const done = without(state.done, action.id);\n return {\n ...state,\n done,\n settled: without(state.settled, action.id),\n expanded: state.expanded ?? action.id,\n message: `${titleOf(action.steps, action.id)} marked as not done. ${done.length} of ${action.steps.length} complete.`,\n };\n }\n case \"settle\": {\n if (!state.done.includes(action.id) || state.settled.includes(action.id)) return state;\n let expanded = state.expanded;\n // The step that just finished hands the open panel to the next unfinished step, wrapping to the top.\n if (expanded === action.id) {\n const order = action.steps.map((step) => step.id);\n const start = order.indexOf(action.id);\n expanded =\n order\n .map((_, offset) => order[(start + offset + 1) % order.length]!)\n .find((id) => !state.done.includes(id)) ?? null;\n }\n return { ...state, settled: ordered([...state.settled, action.id], action.steps), expanded };\n }\n case \"expand\":\n return { ...state, expanded: state.expanded === action.id ? null : action.id };\n case \"start\":\n return { ...state, errors: omit(state.errors, action.id) };\n case \"fail\":\n return {\n ...state,\n errors: { ...state.errors, [action.id]: action.message },\n message: action.message,\n };\n case \"group\":\n return { ...state, groupOpen: !state.groupOpen };\n case \"hide\":\n return { ...state, hidden: !state.hidden };\n }\n}\n\nconst Chevron = () => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\n/**\n * A box that opens and closes its height (a grid track going between 0fr and 1fr).\n * Closed, it is visibility: hidden once folded, so it leaves the tab order.\n */\nfunction Collapse({ show, children }: { show: boolean; children: ReactNode }) {\n return (\n <div data-shown={show || undefined} className=\"checklist-collapse\">\n <div>{children}</div>\n </div>\n );\n}\n\n/** Every label the slot can show sits invisibly underneath, so a swap never changes the slot's size. */\nfunction SwapLabel({ text, options }: { text: string; options: string[] }) {\n return (\n <span className=\"checklist-swap\" aria-hidden=\"true\">\n {options.map((option, index) => (\n <span key={index} className=\"checklist-swap-sizer\">\n {option}\n </span>\n ))}\n <SwapText swapKey={text} motion=\"rise\" className=\"checklist-swap-item\">\n {text}\n </SwapText>\n </span>\n );\n}\n\n/** The ring's stroke fills on a spring as steps are checked; once every step is done a tick draws in its center. */\nfunction ProgressRing({ done, total }: { done: number; total: number }) {\n const ratio = total ? done / total : 0;\n const complete = total > 0 && done === total;\n return (\n <span\n className=\"checklist-ring\"\n role=\"progressbar\"\n aria-label=\"Setup progress\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={done}\n aria-valuetext={`${done} of ${total} steps done`}\n >\n <svg viewBox=\"0 0 40 40\" fill=\"none\" aria-hidden=\"true\">\n <circle className=\"checklist-ring-track\" cx=\"20\" cy=\"20\" r=\"17\" strokeWidth={3} />\n <g transform=\"rotate(-90 20 20)\">\n <circle\n className=\"checklist-ring-fill\"\n cx=\"20\"\n cy=\"20\"\n r=\"17\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n pathLength={1}\n data-started={ratio > 0 ? \"\" : undefined}\n style={{ \"--ratio\": ratio } as CSSProperties}\n />\n </g>\n </svg>\n <span className=\"checklist-ring-tick\" aria-hidden=\"true\">\n <SwapText swapKey={complete ? \"tick\" : \"\"} motion=\"glyph\" className=\"grid place-items-center\">\n {complete ? (\n <svg viewBox=\"0 0 40 40\" fill=\"none\">\n <path\n className=\"checklist-draw\"\n pathLength={1}\n d=\"M13.5 20.5 18 25l8.5-9.5\"\n stroke=\"currentColor\"\n strokeWidth={2.25}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n ) : null}\n </SwapText>\n </span>\n </span>\n );\n}\n\n/** The fill grows from the center while the tick draws from its short stroke; unchecking retracts both quickly. */\nfunction CheckButton({\n checked,\n labelledBy,\n onToggle,\n}: {\n checked: boolean;\n labelledBy: string;\n onToggle: () => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={checked}\n aria-labelledby={labelledBy}\n className=\"checklist-check\"\n data-check=\"\"\n onClick={onToggle}\n >\n <span className=\"checklist-check-visual\" aria-hidden=\"true\">\n <span className=\"checklist-check-fill\" />\n <svg className=\"checklist-check-mark\" viewBox=\"0 0 22 22\" fill=\"none\">\n <path\n pathLength={1}\n d=\"M6.75 11.25 9.75 14.25 15.25 8.25\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n </button>\n );\n}\n\ninterface StepItemProps {\n step: OnboardingStep;\n baseId: string;\n done: boolean;\n settled: boolean;\n expanded: boolean;\n error: string | undefined;\n onToggle: () => void;\n onExpand: () => void;\n onRun: () => Promise<void>;\n}\n\nfunction StepItem({\n step,\n baseId,\n done,\n settled,\n expanded,\n error,\n onToggle,\n onExpand,\n onRun,\n}: StepItemProps) {\n const titleId = `${baseId}-${step.id}-title`;\n const panelId = `${baseId}-${step.id}-panel`;\n // The message stays while its slot folds away.\n const [lastError, setLastError] = useState(error);\n if (error && error !== lastError) setLastError(error);\n return (\n <li\n data-step={step.id}\n data-done={done || undefined}\n data-current={expanded || undefined}\n data-open={settled ? undefined : \"\"}\n >\n <Collapse show={!settled}>\n <div className=\"checklist-step-inner\">\n <CheckButton checked={done} labelledBy={titleId} onToggle={onToggle} />\n <div className=\"checklist-step-main\">\n <button\n type=\"button\"\n className=\"checklist-step-title\"\n data-title=\"\"\n aria-expanded={expanded}\n aria-controls={panelId}\n onClick={onExpand}\n >\n <span id={titleId} className=\"checklist-title-text\">\n {step.title}\n </span>\n </button>\n <Collapse show={expanded}>\n <div id={panelId} role=\"region\" aria-labelledby={titleId} className=\"checklist-panel-inner\">\n {step.description ? <p className=\"checklist-description\">{step.description}</p> : null}\n <Collapse show={Boolean(error)}>\n <p role=\"alert\" className=\"checklist-error\">\n {lastError}\n </p>\n </Collapse>\n {step.actionLabel ? (\n // The label stays put through the whole action: only the icon beside it changes.\n <ActionButton\n variant=\"primary\"\n size=\"sm\"\n className=\"mt-3\"\n data-primary=\"\"\n pendingLabel={step.actionLabel}\n successLabel={step.actionLabel}\n onAction={onRun}\n >\n {step.actionLabel}\n </ActionButton>\n ) : null}\n </div>\n </Collapse>\n </div>\n </div>\n </Collapse>\n </li>\n );\n}\n\nexport const OnboardingChecklist = forwardRef<HTMLElement, OnboardingChecklistProps>(\n function OnboardingChecklist(\n {\n title,\n doneTitle = \"You’re all set\",\n steps,\n defaultCompleted = [],\n onCompletedChange,\n defaultHidden = false,\n onHiddenChange,\n className,\n },\n ref,\n ) {\n const baseId = useId();\n const [state, dispatch] = useReducer(\n reducer,\n { steps, completed: defaultCompleted, hidden: defaultHidden },\n init,\n );\n const root = useRef<HTMLElement | null>(null);\n const refs = useMemo(() => mergeRefs(ref, root), [ref]);\n const timers = useRef(new Map<string, ReturnType<typeof setTimeout>>());\n const focusRequest = useRef<\"next\" | { id: string } | null>(null);\n const reportCompleted = useRef(onCompletedChange);\n const reported = useRef(state.done);\n\n useEffect(() => {\n reportCompleted.current = onCompletedChange;\n });\n useEffect(() => {\n if (reported.current === state.done) return;\n reported.current = state.done;\n reportCompleted.current?.(state.done);\n }, [state.done]);\n useEffect(() => {\n const pending = timers.current;\n return () => pending.forEach(clearTimeout);\n }, []);\n // Focus moves after the commit that opens its target: the next step's action, or the step reopened from the completed row.\n useEffect(() => {\n const request = focusRequest.current;\n const node = root.current;\n if (!request || !node) return;\n focusRequest.current = null;\n let target: HTMLElement | null;\n if (request === \"next\") {\n const next = state.expanded\n ? node.querySelector<HTMLElement>(`[data-step=\"${state.expanded}\"][data-open]`)\n : null;\n target =\n next?.querySelector<HTMLElement>(\"[data-primary]\") ??\n next?.querySelector<HTMLElement>(\"[data-title]\") ??\n node.querySelector<HTMLElement>(\"[data-group-toggle]\");\n } else {\n target = node.querySelector<HTMLElement>(`[data-step=\"${request.id}\"][data-open] [data-check]`);\n }\n target?.focus({ preventScroll: true });\n });\n\n function check(id: string) {\n dispatch({ type: \"check\", id, steps });\n if (timers.current.has(id)) return;\n timers.current.set(\n id,\n setTimeout(() => {\n timers.current.delete(id);\n if (root.current?.querySelector(`[data-step=\"${id}\"]`)?.contains(document.activeElement))\n focusRequest.current = \"next\";\n dispatch({ type: \"settle\", id, steps });\n }, SETTLE_MS),\n );\n }\n\n function uncheck(id: string, fromGroup: boolean) {\n clearTimeout(timers.current.get(id));\n timers.current.delete(id);\n if (fromGroup) focusRequest.current = { id };\n dispatch({ type: \"uncheck\", id, steps });\n }\n\n async function run(step: OnboardingStep) {\n if (!step.onAction || state.done.includes(step.id)) return;\n dispatch({ type: \"start\", id: step.id, steps });\n try {\n await step.onAction();\n } catch (error) {\n dispatch({\n type: \"fail\",\n id: step.id,\n message:\n error instanceof Error && error.message ? error.message : \"That didn’t work. Try again.\",\n });\n // The button goes back to rest on a rejection.\n throw error;\n }\n check(step.id);\n }\n\n function toggleHidden() {\n dispatch({ type: \"hide\" });\n onHiddenChange?.(!state.hidden);\n }\n\n /** Up and Down walk the step titles, Home and End jump to the first and last. */\n function navigate(event: KeyboardEvent<HTMLUListElement>) {\n const target = event.target as HTMLElement;\n if (!target.matches(\"[data-title]\") || ![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key))\n return;\n const titles = Array.from(\n event.currentTarget.querySelectorAll<HTMLElement>(\"li[data-open] [data-title]\"),\n );\n const index = titles.indexOf(target);\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? titles.length - 1\n : (index + (event.key === \"ArrowDown\" ? 1 : -1) + titles.length) % titles.length;\n event.preventDefault();\n titles[next]?.focus();\n }\n\n const total = steps.length;\n const doneCount = state.done.length;\n const allDone = total > 0 && doneCount === total;\n const completed = steps.filter((step) => state.settled.includes(step.id));\n const titleId = `${baseId}-title`;\n const bodyId = `${baseId}-body`;\n const groupId = `${baseId}-completed`;\n\n return (\n <section\n ref={refs}\n aria-labelledby={titleId}\n data-slot=\"onboarding-checklist\"\n data-complete={allDone || undefined}\n data-hidden={state.hidden || undefined}\n className={cn(\"checklist box-border font-sans\", className)}\n >\n <div className=\"checklist-header\">\n <ProgressRing done={doneCount} total={total} />\n <div className=\"checklist-heading\">\n <h3 id={titleId} className=\"checklist-title\">\n <span className=\"sr-only\">{allDone ? doneTitle : title}</span>\n <SwapLabel text={allDone ? doneTitle : title} options={[title, doneTitle]} />\n </h3>\n <p className=\"checklist-count\">\n <span className=\"sr-only\">\n {doneCount} of {total} done\n </span>\n <span className=\"checklist-count-visual\" aria-hidden=\"true\">\n <RollingNumber word={String(doneCount)} />\n &nbsp;of {total} done\n </span>\n </p>\n </div>\n <button\n type=\"button\"\n className=\"checklist-hide\"\n aria-expanded={!state.hidden}\n aria-controls={bodyId}\n onClick={toggleHidden}\n >\n <span className=\"checklist-hide-label\">\n <SwapLabel text={state.hidden ? \"Show\" : \"Hide\"} options={[\"Hide\", \"Show\"]} />\n </span>\n <span className=\"sr-only\">{state.hidden ? \"Show\" : \"Hide\"} checklist</span>\n <span className=\"checklist-chevron\" aria-hidden=\"true\" data-flipped={state.hidden || undefined}>\n <Chevron />\n </span>\n </button>\n </div>\n <div id={bodyId} data-shown={state.hidden ? undefined : \"\"} className=\"checklist-collapse\">\n <div>\n <div className=\"checklist-body-inner\">\n <ul\n className=\"checklist-list\"\n aria-label=\"Steps to do\"\n aria-hidden={completed.length === total ? true : undefined}\n onKeyDown={navigate}\n >\n {steps.map((step) => (\n <StepItem\n key={step.id}\n step={step}\n baseId={baseId}\n done={state.done.includes(step.id)}\n settled={state.settled.includes(step.id)}\n expanded={state.expanded === step.id}\n error={state.errors[step.id]}\n onToggle={() =>\n state.done.includes(step.id) ? uncheck(step.id, false) : check(step.id)\n }\n onExpand={() => dispatch({ type: \"expand\", id: step.id, steps })}\n onRun={() => run(step)}\n />\n ))}\n </ul>\n <Collapse show={completed.length > 0}>\n <button\n type=\"button\"\n className=\"checklist-group-toggle\"\n data-group-toggle=\"\"\n aria-expanded={state.groupOpen}\n aria-controls={groupId}\n onClick={() => dispatch({ type: \"group\" })}\n >\n <span className=\"sr-only\">{completed.length} completed</span>\n <span className=\"checklist-count-visual\" aria-hidden=\"true\">\n <RollingNumber word={String(completed.length)} />\n &nbsp;completed\n </span>\n <span\n className=\"checklist-chevron\"\n aria-hidden=\"true\"\n data-flipped={state.groupOpen ? undefined : \"\"}\n >\n <Chevron />\n </span>\n </button>\n <Collapse show={state.groupOpen}>\n <div id={groupId}>\n <ul className=\"checklist-list\" aria-label=\"Completed steps\">\n {steps.map((step) => {\n const doneId = `${baseId}-${step.id}-done`;\n return (\n <li key={step.id} data-completed-step={step.id} data-done=\"\">\n <Collapse show={state.settled.includes(step.id)}>\n <div className=\"checklist-step-inner\">\n <CheckButton checked labelledBy={doneId} onToggle={() => uncheck(step.id, true)} />\n <span className=\"checklist-done-title\">\n <span id={doneId} className=\"checklist-title-text\">\n {step.title}\n </span>\n </span>\n </div>\n </Collapse>\n </li>\n );\n })}\n </ul>\n </div>\n </Collapse>\n </Collapse>\n </div>\n </div>\n </div>\n <span className=\"sr-only\" role=\"status\">\n {state.message}\n </span>\n </section>\n );\n },\n);\n"],"mappings":"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"}