@boxcustodia/library 2.0.0-alpha.19 → 2.0.0-alpha.20

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 (265) hide show
  1. package/dist/components/button/button.cjs.js +1 -1
  2. package/dist/components/button/button.es.js +19 -18
  3. package/dist/components/button/components/base-button.cjs.js +1 -1
  4. package/dist/components/button/components/base-button.es.js +20 -20
  5. package/dist/components/calendar/calendar.cjs.js +1 -1
  6. package/dist/components/calendar/calendar.es.js +1 -0
  7. package/dist/components/date-picker/date-input.cjs.js +1 -1
  8. package/dist/components/date-picker/date-input.es.js +92 -75
  9. package/dist/components/date-picker/date-picker.cjs.js +1 -1
  10. package/dist/components/date-picker/date-picker.es.js +104 -95
  11. package/dist/components/date-picker/date-picker.utils.cjs.js +1 -1
  12. package/dist/components/date-picker/date-picker.utils.es.js +51 -43
  13. package/dist/components/date-picker/use-hidden-field-value.cjs.js +1 -0
  14. package/dist/components/date-picker/use-hidden-field-value.es.js +11 -0
  15. package/dist/components/menu/menu.es.js +1 -9
  16. package/dist/components/otp/otp.cjs.js +2 -0
  17. package/dist/components/otp/otp.es.js +93 -0
  18. package/dist/components/password/password.cjs.js +1 -1
  19. package/dist/components/password/password.es.js +2 -2
  20. package/dist/components/select/select.cjs.js +1 -1
  21. package/dist/components/select/select.es.js +68 -60
  22. package/dist/hooks/internal/is-apple-device.cjs.js +1 -0
  23. package/dist/hooks/internal/is-apple-device.es.js +9 -0
  24. package/dist/hooks/internal/use-latest-ref.cjs.js +1 -0
  25. package/dist/hooks/internal/use-latest-ref.es.js +11 -0
  26. package/dist/hooks/use-array/use-array.cjs.js +1 -1
  27. package/dist/hooks/use-array/use-array.es.js +54 -42
  28. package/dist/hooks/use-async/use-async.cjs.js +1 -1
  29. package/dist/hooks/use-async/use-async.es.js +53 -20
  30. package/dist/hooks/use-boolean/use-boolean.cjs.js +1 -0
  31. package/dist/hooks/use-boolean/use-boolean.es.js +25 -0
  32. package/dist/hooks/use-click-outside/use-click-outside.cjs.js +1 -1
  33. package/dist/hooks/use-click-outside/use-click-outside.es.js +26 -12
  34. package/dist/hooks/use-debounce-callback/use-debounced-callback.cjs.js +1 -1
  35. package/dist/hooks/use-debounce-callback/use-debounced-callback.es.js +27 -10
  36. package/dist/hooks/use-debounce-value/use-debounced-value.cjs.js +1 -1
  37. package/dist/hooks/use-debounce-value/use-debounced-value.es.js +7 -9
  38. package/dist/hooks/use-disclosure/use-disclosure.cjs.js +1 -1
  39. package/dist/hooks/use-disclosure/use-disclosure.es.js +21 -11
  40. package/dist/hooks/use-document-title/use-document-title.cjs.js +1 -1
  41. package/dist/hooks/use-document-title/use-document-title.es.js +14 -12
  42. package/dist/hooks/use-event-listener/use-event-listener.cjs.js +1 -1
  43. package/dist/hooks/use-event-listener/use-event-listener.es.js +17 -9
  44. package/dist/hooks/use-hotkey/use-hotkey.cjs.js +1 -1
  45. package/dist/hooks/use-hotkey/use-hotkey.es.js +30 -14
  46. package/dist/hooks/use-hotkey/utils/is-input-field.cjs.js +1 -1
  47. package/dist/hooks/use-hotkey/utils/is-input-field.es.js +4 -2
  48. package/dist/hooks/use-hotkey/utils/match-and-run.cjs.js +1 -0
  49. package/dist/hooks/use-hotkey/utils/match-and-run.es.js +12 -0
  50. package/dist/hooks/use-hotkey/utils/match-key-modifiers.cjs.js +1 -1
  51. package/dist/hooks/use-hotkey/utils/match-key-modifiers.es.js +13 -12
  52. package/dist/hooks/use-hover/use-hover.cjs.js +1 -1
  53. package/dist/hooks/use-hover/use-hover.es.js +32 -17
  54. package/dist/hooks/use-is-visible/use-is-visible.cjs.js +1 -1
  55. package/dist/hooks/use-is-visible/use-is-visible.es.js +31 -27
  56. package/dist/hooks/use-local-storage/use-local-storage.cjs.js +1 -1
  57. package/dist/hooks/use-local-storage/use-local-storage.es.js +52 -20
  58. package/dist/hooks/use-media-query/use-media-query.cjs.js +1 -1
  59. package/dist/hooks/use-media-query/use-media-query.es.js +21 -11
  60. package/dist/hooks/use-mutation/use-mutation.cjs.js +1 -1
  61. package/dist/hooks/use-mutation/use-mutation.es.js +36 -22
  62. package/dist/hooks/use-object/use-object.cjs.js +1 -1
  63. package/dist/hooks/use-object/use-object.es.js +26 -22
  64. package/dist/hooks/use-prevent-page-close/use-prevent-page-close.cjs.js +1 -0
  65. package/dist/hooks/use-prevent-page-close/use-prevent-page-close.es.js +14 -0
  66. package/dist/hooks/use-step/use-step.cjs.js +1 -1
  67. package/dist/hooks/use-step/use-step.es.js +25 -24
  68. package/dist/index.cjs.js +1 -1
  69. package/dist/index.es.js +308 -300
  70. package/dist/src/components/date-picker/date-picker.utils.d.ts +17 -0
  71. package/dist/src/components/date-picker/use-hidden-field-value.d.ts +12 -0
  72. package/dist/src/components/index.d.ts +1 -0
  73. package/dist/src/hooks/index.d.ts +2 -2
  74. package/dist/src/hooks/internal/index.d.ts +2 -0
  75. package/dist/src/hooks/internal/is-apple-device.d.ts +12 -0
  76. package/dist/src/hooks/internal/use-latest-ref.d.ts +12 -0
  77. package/dist/src/hooks/use-array/use-array.d.ts +24 -11
  78. package/dist/src/hooks/use-async/use-async.d.ts +16 -13
  79. package/dist/src/hooks/use-boolean/index.d.ts +1 -0
  80. package/dist/src/hooks/use-boolean/use-boolean.d.ts +15 -0
  81. package/dist/src/hooks/use-boolean/use-boolean.test.d.ts +1 -0
  82. package/dist/src/hooks/use-click-outside/use-click-outside.d.ts +23 -1
  83. package/dist/src/hooks/use-debounce-callback/use-debounced-callback.d.ts +19 -1
  84. package/dist/src/hooks/use-debounce-value/use-debounced-value.d.ts +10 -1
  85. package/dist/src/hooks/use-disclosure/use-disclosure.d.ts +17 -8
  86. package/dist/src/hooks/use-document-title/use-document-title.d.ts +11 -0
  87. package/dist/src/hooks/use-event-listener/use-event-listener.d.ts +18 -1
  88. package/dist/src/hooks/use-hotkey/index.d.ts +2 -1
  89. package/dist/src/hooks/use-hotkey/use-hotkey.d.ts +62 -5
  90. package/dist/src/hooks/use-hotkey/utils/index.d.ts +4 -3
  91. package/dist/src/hooks/use-hotkey/utils/is-input-field.d.ts +12 -2
  92. package/dist/src/hooks/use-hotkey/utils/is-input-field.test.d.ts +1 -0
  93. package/dist/src/hooks/use-hotkey/utils/match-and-run.d.ts +36 -0
  94. package/dist/src/hooks/use-hotkey/utils/match-and-run.test.d.ts +1 -0
  95. package/dist/src/hooks/use-hotkey/utils/match-key-modifiers.d.ts +20 -6
  96. package/dist/src/hooks/use-hotkey/utils/match-key-modifiers.test.d.ts +1 -0
  97. package/dist/src/hooks/use-hover/use-hover.d.ts +8 -4
  98. package/dist/src/hooks/use-is-visible/use-is-visible.d.ts +28 -4
  99. package/dist/src/hooks/use-local-storage/use-local-storage.d.ts +13 -2
  100. package/dist/src/hooks/use-media-query/use-media-query.d.ts +10 -1
  101. package/dist/src/hooks/use-media-query/use-media-query.test.d.ts +1 -0
  102. package/dist/src/hooks/use-mutation/use-mutation.d.ts +18 -11
  103. package/dist/src/hooks/use-object/use-object.d.ts +15 -6
  104. package/dist/src/hooks/use-prevent-page-close/index.d.ts +1 -0
  105. package/dist/src/hooks/use-prevent-page-close/use-prevent-page-close.d.ts +10 -0
  106. package/dist/src/hooks/use-prevent-page-close/use-prevent-page-close.test.d.ts +1 -0
  107. package/dist/src/hooks/use-step/use-step.d.ts +18 -11
  108. package/dist/src/utils/form.d.ts +10 -0
  109. package/package.json +1 -1
  110. package/src/components/alert-dialog/alert-dialog.test.tsx +13 -9
  111. package/src/components/auto-complete/auto-complete.test.tsx +4 -14
  112. package/src/components/avatar/avatar.test.tsx +7 -12
  113. package/src/components/button/button.test.tsx +10 -15
  114. package/src/components/button/button.tsx +14 -9
  115. package/src/components/button/components/base-button.tsx +2 -4
  116. package/src/components/calendar/calendar.test.tsx +12 -19
  117. package/src/components/calendar/calendar.tsx +4 -0
  118. package/src/components/card/card.test.tsx +4 -6
  119. package/src/components/checkbox/checkbox.test.tsx +12 -8
  120. package/src/components/checkbox-group/checkbox-group.test.tsx +7 -8
  121. package/src/components/combobox/combobox.test.tsx +24 -21
  122. package/src/components/date-picker/date-input-form.test.tsx +77 -0
  123. package/src/components/date-picker/date-input.stories.tsx +30 -18
  124. package/src/components/date-picker/date-input.tsx +77 -44
  125. package/src/components/date-picker/date-picker.stories.tsx +31 -1
  126. package/src/components/date-picker/date-picker.test.tsx +3 -13
  127. package/src/components/date-picker/date-picker.tsx +35 -16
  128. package/src/components/date-picker/date-picker.utils.test.ts +32 -14
  129. package/src/components/date-picker/date-picker.utils.ts +33 -0
  130. package/src/components/date-picker/use-date-input-popover.test.ts +3 -1
  131. package/src/components/date-picker/use-hidden-field-value.ts +23 -0
  132. package/src/components/dialog/dialog.test.tsx +10 -8
  133. package/src/components/dropzone/dropzone.test.tsx +11 -13
  134. package/src/components/empty/empty.test.tsx +4 -3
  135. package/src/components/field/field.test.tsx +12 -13
  136. package/src/components/form/form.stories.tsx +16 -1
  137. package/src/components/index.ts +1 -0
  138. package/src/components/label/label.test.tsx +3 -3
  139. package/src/components/menu/menu.tsx +1 -5
  140. package/src/components/number-input/number-input.test.tsx +6 -2
  141. package/src/components/password/password.test.tsx +20 -6
  142. package/src/components/password/password.tsx +2 -2
  143. package/src/components/popover/popover.test.tsx +4 -4
  144. package/src/components/progress/progress.test.tsx +7 -8
  145. package/src/components/radio-group/radio-group.test.tsx +17 -11
  146. package/src/components/select/select.test.tsx +10 -10
  147. package/src/components/select/select.tsx +9 -1
  148. package/src/components/stepper/stepper.stories.tsx +11 -15
  149. package/src/components/stepper/stepper.test.tsx +6 -4
  150. package/src/components/switch/switch.test.tsx +3 -3
  151. package/src/components/table/table.test.tsx +9 -3
  152. package/src/components/tabs/tabs.test.tsx +6 -2
  153. package/src/components/tag/tag.test.tsx +1 -3
  154. package/src/components/textarea/textarea.test.tsx +4 -1
  155. package/src/components/timeline/timeline.test.tsx +10 -5
  156. package/src/components/toast/toast.test.tsx +11 -14
  157. package/src/components/tooltip/tooltip.test.tsx +1 -5
  158. package/src/components/tree/tree.test.tsx +3 -1
  159. package/src/hooks/index.ts +2 -2
  160. package/src/hooks/internal/index.ts +2 -0
  161. package/src/hooks/internal/is-apple-device.test.ts +41 -0
  162. package/src/hooks/internal/is-apple-device.ts +33 -0
  163. package/src/hooks/internal/use-isomorphic-layout-effect.ts +3 -1
  164. package/src/hooks/internal/use-latest-ref.ts +21 -0
  165. package/src/hooks/use-array/use-array.stories.tsx +435 -64
  166. package/src/hooks/use-array/use-array.test.tsx +398 -15
  167. package/src/hooks/use-array/use-array.ts +105 -66
  168. package/src/hooks/use-async/use-async.stories.tsx +255 -131
  169. package/src/hooks/use-async/use-async.test.ts +397 -0
  170. package/src/hooks/use-async/use-async.ts +117 -39
  171. package/src/hooks/use-boolean/index.ts +1 -0
  172. package/src/hooks/use-boolean/use-boolean.stories.tsx +377 -0
  173. package/src/hooks/use-boolean/use-boolean.test.tsx +177 -0
  174. package/src/hooks/use-boolean/use-boolean.ts +50 -0
  175. package/src/hooks/use-click-outside/use-click-outside.stories.tsx +188 -18
  176. package/src/hooks/use-click-outside/use-click-outside.test.tsx +89 -10
  177. package/src/hooks/use-click-outside/use-click-outside.ts +62 -16
  178. package/src/hooks/use-debounce-callback/use-debounced-callback.stories.tsx +141 -41
  179. package/src/hooks/use-debounce-callback/use-debounced-callback.test.ts +217 -9
  180. package/src/hooks/use-debounce-callback/use-debounced-callback.ts +71 -11
  181. package/src/hooks/use-debounce-value/use-debounced-value.stories.tsx +247 -47
  182. package/src/hooks/use-debounce-value/use-debounced-value.test.ts +105 -10
  183. package/src/hooks/use-debounce-value/use-debounced-value.ts +19 -10
  184. package/src/hooks/use-disclosure/use-disclosure.stories.tsx +305 -14
  185. package/src/hooks/use-disclosure/use-disclosure.test.ts +198 -50
  186. package/src/hooks/use-disclosure/use-disclosure.ts +49 -29
  187. package/src/hooks/use-document-title/use-document-title.stories.tsx +54 -0
  188. package/src/hooks/use-document-title/use-document-title.test.tsx +26 -0
  189. package/src/hooks/use-document-title/{use-document-title.tsx → use-document-title.ts} +17 -3
  190. package/src/hooks/use-event-listener/use-event-listener.stories.tsx +105 -9
  191. package/src/hooks/use-event-listener/use-event-listener.test.tsx +77 -10
  192. package/src/hooks/use-event-listener/use-event-listener.ts +71 -11
  193. package/src/hooks/use-focus-trap/use-focus-trap.test.ts +31 -6
  194. package/src/hooks/use-focus-trap/use-focus-trap.ts +3 -2
  195. package/src/hooks/use-hotkey/index.ts +9 -1
  196. package/src/hooks/use-hotkey/use-hotkey.stories.tsx +279 -74
  197. package/src/hooks/use-hotkey/use-hotkey.test.tsx +286 -34
  198. package/src/hooks/use-hotkey/use-hotkey.ts +141 -17
  199. package/src/hooks/use-hotkey/utils/index.ts +8 -3
  200. package/src/hooks/use-hotkey/utils/is-input-field.test.ts +78 -0
  201. package/src/hooks/use-hotkey/utils/is-input-field.ts +31 -10
  202. package/src/hooks/use-hotkey/utils/match-and-run.test.ts +203 -0
  203. package/src/hooks/use-hotkey/utils/match-and-run.ts +62 -0
  204. package/src/hooks/use-hotkey/utils/match-key-modifiers.test.ts +65 -0
  205. package/src/hooks/use-hotkey/utils/match-key-modifiers.ts +39 -12
  206. package/src/hooks/use-hover/use-hover.stories.tsx +258 -80
  207. package/src/hooks/use-hover/use-hover.test.tsx +266 -26
  208. package/src/hooks/use-hover/use-hover.tsx +93 -28
  209. package/src/hooks/use-is-visible/use-is-visible.stories.tsx +193 -46
  210. package/src/hooks/use-is-visible/use-is-visible.test.tsx +235 -7
  211. package/src/hooks/use-is-visible/use-is-visible.ts +114 -0
  212. package/src/hooks/use-local-storage/use-local-storage.stories.tsx +129 -29
  213. package/src/hooks/use-local-storage/use-local-storage.test.ts +106 -41
  214. package/src/hooks/use-local-storage/use-local-storage.ts +100 -31
  215. package/src/hooks/use-media-query/use-media-query.stories.tsx +86 -26
  216. package/src/hooks/use-media-query/use-media-query.test.ts +132 -0
  217. package/src/hooks/use-media-query/use-media-query.ts +39 -14
  218. package/src/hooks/use-memoized-fn/use-memoized-fn.ts +0 -1
  219. package/src/hooks/use-mutation/use-mutation.stories.tsx +260 -94
  220. package/src/hooks/use-mutation/use-mutation.test.ts +359 -0
  221. package/src/hooks/use-mutation/use-mutation.ts +97 -0
  222. package/src/hooks/use-object/use-object.stories.tsx +310 -79
  223. package/src/hooks/use-object/use-object.test.tsx +235 -56
  224. package/src/hooks/use-object/use-object.ts +59 -0
  225. package/src/hooks/use-pagination/use-pagination.tsx +0 -1
  226. package/src/hooks/use-prevent-page-close/index.ts +1 -0
  227. package/src/hooks/use-prevent-page-close/use-prevent-page-close.stories.tsx +39 -0
  228. package/src/hooks/use-prevent-page-close/use-prevent-page-close.test.ts +89 -0
  229. package/src/hooks/use-prevent-page-close/use-prevent-page-close.ts +27 -0
  230. package/src/hooks/use-range-pagination/use-range-pagination.test.tsx +1 -1
  231. package/src/hooks/use-range-pagination/use-range-pagination.tsx +1 -1
  232. package/src/hooks/use-selection/use-selection.ts +0 -1
  233. package/src/hooks/use-step/use-step.stories.tsx +178 -65
  234. package/src/hooks/use-step/use-step.test.ts +178 -53
  235. package/src/hooks/use-step/use-step.ts +57 -49
  236. package/src/utils/form.test.tsx +13 -8
  237. package/src/utils/form.tsx +10 -0
  238. package/src/utils/functions/getFormData.test.ts +1 -1
  239. package/dist/hooks/use-hotkey/utils/create-hotkey-listener.cjs.js +0 -1
  240. package/dist/hooks/use-hotkey/utils/create-hotkey-listener.es.js +0 -10
  241. package/dist/hooks/use-prevent-close-window/use-prevent-close-window.cjs.js +0 -1
  242. package/dist/hooks/use-prevent-close-window/use-prevent-close-window.es.js +0 -15
  243. package/dist/hooks/use-toggle/use-toggle.cjs.js +0 -1
  244. package/dist/hooks/use-toggle/use-toggle.es.js +0 -10
  245. package/dist/src/hooks/use-hotkey/utils/create-hotkey-listener.d.ts +0 -1
  246. package/dist/src/hooks/use-prevent-close-window/index.d.ts +0 -1
  247. package/dist/src/hooks/use-prevent-close-window/use-prevent-close-window.d.ts +0 -13
  248. package/dist/src/hooks/use-toggle/index.d.ts +0 -1
  249. package/dist/src/hooks/use-toggle/use-toggle.d.ts +0 -3
  250. package/src/hooks/use-async/use-async.test.tsx +0 -68
  251. package/src/hooks/use-hotkey/utils/create-hotkey-listener.ts +0 -25
  252. package/src/hooks/use-is-visible/use-is-visible.tsx +0 -49
  253. package/src/hooks/use-mutation/use-mutation.test.tsx +0 -83
  254. package/src/hooks/use-mutation/use-mutation.tsx +0 -59
  255. package/src/hooks/use-object/use-object.tsx +0 -46
  256. package/src/hooks/use-prevent-close-window/index.ts +0 -1
  257. package/src/hooks/use-prevent-close-window/use-prevent-close-window.stories.tsx +0 -32
  258. package/src/hooks/use-prevent-close-window/use-prevent-close-window.test.ts +0 -79
  259. package/src/hooks/use-prevent-close-window/use-prevent-close-window.ts +0 -33
  260. package/src/hooks/use-toggle/index.ts +0 -1
  261. package/src/hooks/use-toggle/use-toggle.stories.tsx +0 -25
  262. package/src/hooks/use-toggle/use-toggle.test.tsx +0 -64
  263. package/src/hooks/use-toggle/use-toggle.ts +0 -14
  264. /package/dist/src/{hooks/use-prevent-close-window/use-prevent-close-window.test.d.ts → components/date-picker/date-input-form.test.d.ts} +0 -0
  265. /package/dist/src/hooks/{use-toggle/use-toggle.test.d.ts → internal/is-apple-device.test.d.ts} +0 -0
@@ -70,9 +70,9 @@ describe("Switch composite", () => {
70
70
 
71
71
  it("applies classNames.wrapper to wrapper div", () => {
72
72
  render(<Switch classNames={{ wrapper: "cls-wrap" }} />);
73
- expect(document.querySelector('[data-slot="switch"]')?.parentElement).toHaveClass(
74
- "cls-wrap",
75
- );
73
+ expect(
74
+ document.querySelector('[data-slot="switch"]')?.parentElement,
75
+ ).toHaveClass("cls-wrap");
76
76
  });
77
77
 
78
78
  it("applies classNames.thumb to thumb", () => {
@@ -109,7 +109,9 @@ describe("Table data-slots", () => {
109
109
  <tbody />
110
110
  </TableRoot>,
111
111
  );
112
- expect(document.querySelector('[data-slot="table-container"]')).toBeTruthy();
112
+ expect(
113
+ document.querySelector('[data-slot="table-container"]'),
114
+ ).toBeTruthy();
113
115
  expect(document.querySelector('[data-slot="table"]')).toBeTruthy();
114
116
  });
115
117
 
@@ -244,14 +246,18 @@ describe("Table composite extras", () => {
244
246
  });
245
247
 
246
248
  it("applies classNames.thead to thead", () => {
247
- render(<Table data={[]} columns={columns} classNames={{ thead: "cls-thead" }} />);
249
+ render(
250
+ <Table data={[]} columns={columns} classNames={{ thead: "cls-thead" }} />,
251
+ );
248
252
  expect(document.querySelector('[data-slot="table-header"]')).toHaveClass(
249
253
  "cls-thead",
250
254
  );
251
255
  });
252
256
 
253
257
  it("applies classNames.td to body cells", () => {
254
- render(<Table data={data} columns={columns} classNames={{ td: "cls-td" }} />);
258
+ render(
259
+ <Table data={data} columns={columns} classNames={{ td: "cls-td" }} />,
260
+ );
255
261
  const cells = document.querySelectorAll('[data-slot="table-cell"]');
256
262
  expect(cells[0]).toHaveClass("cls-td");
257
263
  });
@@ -78,7 +78,9 @@ describe("Tabs data-slots", () => {
78
78
  <TabList />
79
79
  </Tabs>,
80
80
  );
81
- expect(document.querySelector('[data-slot="tabs-list"]')).toBeInTheDocument();
81
+ expect(
82
+ document.querySelector('[data-slot="tabs-list"]'),
83
+ ).toBeInTheDocument();
82
84
  });
83
85
 
84
86
  it("sets data-slot='tab-indicator' inside list", () => {
@@ -100,7 +102,9 @@ describe("Tabs data-slots", () => {
100
102
  </TabList>
101
103
  </Tabs>,
102
104
  );
103
- expect(document.querySelector('[data-slot="tabs-tab"]')).toBeInTheDocument();
105
+ expect(
106
+ document.querySelector('[data-slot="tabs-tab"]'),
107
+ ).toBeInTheDocument();
104
108
  });
105
109
 
106
110
  it("sets data-slot='tabs-content' on panel", () => {
@@ -35,9 +35,7 @@ describe("Tag variants", () => {
35
35
 
36
36
  describe("Tag render prop", () => {
37
37
  it("renders as anchor when render prop provided", () => {
38
- render(
39
- <Tag render={<a href="/test" />}>Link tag</Tag>,
40
- );
38
+ render(<Tag render={<a href="/test" />}>Link tag</Tag>);
41
39
  expect(screen.getByRole("link")).toBeInTheDocument();
42
40
  expect(screen.getByRole("link")).toHaveTextContent("Link tag");
43
41
  });
@@ -11,7 +11,10 @@ describe("Textarea component", () => {
11
11
 
12
12
  it("sets data-slot='textarea'", () => {
13
13
  render(<Textarea />);
14
- expect(screen.getByRole("textbox")).toHaveAttribute("data-slot", "textarea");
14
+ expect(screen.getByRole("textbox")).toHaveAttribute(
15
+ "data-slot",
16
+ "textarea",
17
+ );
15
18
  });
16
19
 
17
20
  it("applies className", () => {
@@ -21,7 +21,9 @@ const defaultItems = [
21
21
  describe("TimelineRoot", () => {
22
22
  it("renders with data-slot='timeline'", () => {
23
23
  render(<TimelineRoot />);
24
- expect(document.querySelector('[data-slot="timeline"]')).toBeInTheDocument();
24
+ expect(
25
+ document.querySelector('[data-slot="timeline"]'),
26
+ ).toBeInTheDocument();
25
27
  });
26
28
 
27
29
  it("defaults to vertical orientation", () => {
@@ -181,7 +183,10 @@ describe("Timeline composite", () => {
181
183
 
182
184
  it("applies classNames.item to timeline items", () => {
183
185
  render(
184
- <Timeline items={[{ title: "T1" }]} classNames={{ item: "custom-item" }} />,
186
+ <Timeline
187
+ items={[{ title: "T1" }]}
188
+ classNames={{ item: "custom-item" }}
189
+ />,
185
190
  );
186
191
  expect(document.querySelector('[data-slot="timeline-item"]')).toHaveClass(
187
192
  "custom-item",
@@ -195,8 +200,8 @@ describe("Timeline composite", () => {
195
200
  classNames={{ content: "custom-content" }}
196
201
  />,
197
202
  );
198
- expect(document.querySelector('[data-slot="timeline-content"]')).toHaveClass(
199
- "custom-content",
200
- );
203
+ expect(
204
+ document.querySelector('[data-slot="timeline-content"]'),
205
+ ).toHaveClass("custom-content");
201
206
  });
202
207
  });
@@ -1,11 +1,10 @@
1
- import { renderHook } from "@testing-library/react";
2
- import { render, screen } from "@testing-library/react";
1
+ import { render, renderHook, screen } from "@testing-library/react";
3
2
  import userEvent from "@testing-library/user-event";
4
3
  import { describe, expect, it } from "vitest";
5
4
  import {
5
+ createToastManager,
6
6
  ToastPrimitive,
7
7
  ToastProvider,
8
- createToastManager,
9
8
  toast,
10
9
  useToastManager,
11
10
  } from "../toast";
@@ -52,7 +51,9 @@ describe("Toast component", () => {
52
51
  renderWithProvider(<ToastTrigger variant="success" description="test" />);
53
52
  await userEvent.click(screen.getByText("Show toast"));
54
53
  await screen.findByText("test");
55
- const toastEl = document.querySelector('[data-slot="toast"]') as HTMLElement;
54
+ const toastEl = document.querySelector(
55
+ '[data-slot="toast"]',
56
+ ) as HTMLElement;
56
57
  expect(toastEl.className).toContain("ring-success");
57
58
  });
58
59
  });
@@ -87,7 +88,9 @@ describe("Toast variants", () => {
87
88
  renderWithProvider(<ToastTrigger variant={variant} description="msg" />);
88
89
  await userEvent.click(screen.getByText("Show toast"));
89
90
  await screen.findByText("msg");
90
- const toastEl = document.querySelector('[data-slot="toast"]') as HTMLElement;
91
+ const toastEl = document.querySelector(
92
+ '[data-slot="toast"]',
93
+ ) as HTMLElement;
91
94
  expect(toastEl.className).toContain(ringClass);
92
95
  });
93
96
  });
@@ -215,9 +218,7 @@ describe("Toast manager.update", () => {
215
218
  Add
216
219
  </button>
217
220
  <button
218
- onClick={() =>
219
- manager.update("upd-id", { description: "Updated" })
220
- }
221
+ onClick={() => manager.update("upd-id", { description: "Updated" })}
221
222
  >
222
223
  Update
223
224
  </button>
@@ -264,16 +265,12 @@ describe("Toast dedup", () => {
264
265
  return (
265
266
  <>
266
267
  <button
267
- onClick={() =>
268
- manager.add({ id: "dup-id", description: "First" })
269
- }
268
+ onClick={() => manager.add({ id: "dup-id", description: "First" })}
270
269
  >
271
270
  Add First
272
271
  </button>
273
272
  <button
274
- onClick={() =>
275
- manager.add({ id: "dup-id", description: "Second" })
276
- }
273
+ onClick={() => manager.add({ id: "dup-id", description: "Second" })}
277
274
  >
278
275
  Add Second
279
276
  </button>
@@ -127,11 +127,7 @@ describe("Tooltip classNames", () => {
127
127
 
128
128
  it("applies classNames.arrow to arrow", () => {
129
129
  render(
130
- <Tooltip
131
- content="tip"
132
- defaultOpen
133
- classNames={{ arrow: "custom-arrow" }}
134
- >
130
+ <Tooltip content="tip" defaultOpen classNames={{ arrow: "custom-arrow" }}>
135
131
  <Button>t</Button>
136
132
  </Tooltip>,
137
133
  );
@@ -69,7 +69,9 @@ function Harness({
69
69
  className={itemClassName}
70
70
  >
71
71
  <TreeItemLabel className={labelClassName}>
72
- {labelClassName ? item.getItemName() : `Custom: ${item.getItemName()}`}
72
+ {labelClassName
73
+ ? item.getItemName()
74
+ : `Custom: ${item.getItemName()}`}
73
75
  </TreeItemLabel>
74
76
  </TreeItem>
75
77
  ) : (
@@ -1,6 +1,7 @@
1
1
  export { useControllableState } from "@radix-ui/react-use-controllable-state";
2
2
  export * from "./use-array";
3
3
  export * from "./use-async";
4
+ export * from "./use-boolean";
4
5
  export * from "./use-click-outside";
5
6
  export * from "./use-clipboard";
6
7
  export * from "./use-debounce-callback";
@@ -20,8 +21,7 @@ export * from "./use-object";
20
21
  export * from "./use-on-mount";
21
22
  export * from "./use-pagination";
22
23
  export * from "./use-portal";
23
- export * from "./use-prevent-close-window";
24
+ export * from "./use-prevent-page-close";
24
25
  export * from "./use-range-pagination";
25
26
  export * from "./use-selection";
26
27
  export * from "./use-step";
27
- export * from "./use-toggle";
@@ -1,2 +1,4 @@
1
+ export { isAppleDevice } from "./is-apple-device";
1
2
  export { isBrowser } from "./is-browser";
2
3
  export { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect";
4
+ export { useLatestRef } from "./use-latest-ref";
@@ -0,0 +1,41 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { isAppleDevice } from "./is-apple-device";
3
+
4
+ afterEach(() => {
5
+ vi.unstubAllGlobals();
6
+ });
7
+
8
+ describe("isAppleDevice", () => {
9
+ it("returns true when navigator.userAgentData.platform reports macOS", () => {
10
+ vi.stubGlobal("navigator", { userAgentData: { platform: "macOS" } });
11
+ expect(isAppleDevice()).toBe(true);
12
+ });
13
+
14
+ it("returns true for iPhone via legacy navigator.platform", () => {
15
+ vi.stubGlobal("navigator", { platform: "iPhone" });
16
+ expect(isAppleDevice()).toBe(true);
17
+ });
18
+
19
+ it("returns true for iPad via legacy navigator.platform", () => {
20
+ vi.stubGlobal("navigator", { platform: "iPad" });
21
+ expect(isAppleDevice()).toBe(true);
22
+ });
23
+
24
+ it("returns false on a non-Apple platform (Windows)", () => {
25
+ vi.stubGlobal("navigator", { platform: "Win32" });
26
+ expect(isAppleDevice()).toBe(false);
27
+ });
28
+
29
+ it("prefers userAgentData.platform over legacy navigator.platform", () => {
30
+ vi.stubGlobal("navigator", {
31
+ userAgentData: { platform: "Windows" },
32
+ platform: "MacIntel",
33
+ });
34
+ expect(isAppleDevice()).toBe(false);
35
+ });
36
+
37
+ it("returns false when navigator is missing (SSR)", () => {
38
+ vi.stubGlobal("navigator", undefined);
39
+ expect(isAppleDevice()).toBe(false);
40
+ });
41
+ });
@@ -0,0 +1,33 @@
1
+ import { isBrowser } from "./is-browser";
2
+
3
+ /**
4
+ * Structural shape of the modern `navigator.userAgentData` API, which is not
5
+ * yet part of the standard TypeScript DOM lib. Only the `platform` field is
6
+ * read here.
7
+ */
8
+ type NavigatorWithUAData = Navigator & {
9
+ userAgentData?: { platform?: string };
10
+ };
11
+
12
+ const APPLE_PLATFORM_PATTERN = /mac|iphone|ipad|ipod/i;
13
+
14
+ /**
15
+ * Lazily detects whether the current device is an Apple platform (macOS, iOS,
16
+ * iPadOS). Reads `navigator.userAgentData?.platform` when available, falling
17
+ * back to the legacy `navigator.platform`.
18
+ *
19
+ * SSR-safe: returns `false` when there is no `navigator` (e.g. on the server),
20
+ * so the `mod` hotkey modifier deterministically resolves to `ctrl` there.
21
+ *
22
+ * The check runs on every call (not memoized at module-eval) so it can be
23
+ * stubbed per-test and stays correct if the environment changes.
24
+ */
25
+ export const isAppleDevice = (): boolean => {
26
+ if (!isBrowser || typeof navigator === "undefined") return false;
27
+
28
+ const nav = navigator as NavigatorWithUAData;
29
+ const platform = nav.userAgentData?.platform ?? nav.platform;
30
+ if (!platform) return false;
31
+
32
+ return APPLE_PLATFORM_PATTERN.test(platform);
33
+ };
@@ -1,4 +1,6 @@
1
1
  import { useEffect, useLayoutEffect } from "react";
2
2
  import { isBrowser } from "./is-browser";
3
3
 
4
- export const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect;
4
+ export const useIsomorphicLayoutEffect = isBrowser
5
+ ? useLayoutEffect
6
+ : useEffect;
@@ -0,0 +1,21 @@
1
+ import { useRef } from "react";
2
+ import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect";
3
+
4
+ /**
5
+ * Returns a ref whose `.current` always holds the latest value passed in.
6
+ *
7
+ * Internal building block for the handler-stable pattern: hooks that accept
8
+ * user callbacks should read them through a ref so listeners attached to
9
+ * `window`/`document`/elements never need to be re-attached when the consumer
10
+ * passes an inline function.
11
+ *
12
+ * Updates happen in a layout effect so the ref is current before any user
13
+ * effect or commit-phase work runs in the same render.
14
+ */
15
+ export const useLatestRef = <T>(value: T) => {
16
+ const ref = useRef<T>(value);
17
+ useIsomorphicLayoutEffect(() => {
18
+ ref.current = value;
19
+ });
20
+ return ref;
21
+ };