@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
@@ -1,15 +1,22 @@
1
- type Mutation<TArgs extends any[], TReturn> = (...args: TArgs) => Promise<TReturn>;
2
- interface UseMutationOptions<TArgs extends any[], TReturn> {
3
- fn: Mutation<TArgs, TReturn>;
4
- onError?: (error: Error) => void;
5
- onSuccess?: (data: TReturn) => void;
6
- onFinish?: () => void;
1
+ type MutationStatus = "idle" | "pending" | "success" | "error";
2
+ export interface UseMutationOptions<TVariables = void, TData = unknown> {
3
+ fn: (variables: TVariables) => Promise<TData>;
4
+ onMutate?: (variables: TVariables) => void;
5
+ onSuccess?: (data: TData, variables: TVariables) => void;
6
+ onError?: (error: Error, variables: TVariables) => void;
7
+ onSettled?: (data: TData | null, error: Error | null, variables: TVariables) => void;
7
8
  }
8
- interface UseMutationReturn<TArgs extends any[], TReturn> {
9
- mutate: Mutation<TArgs, TReturn>;
10
- loading: boolean;
9
+ export interface UseMutationReturn<TVariables = void, TData = unknown> {
10
+ mutate: (variables: TVariables) => void;
11
+ mutateAsync: (variables: TVariables) => Promise<TData>;
12
+ reset: () => void;
13
+ data: TData | null;
11
14
  error: Error | null;
12
- data: TReturn | null;
15
+ status: MutationStatus;
16
+ isIdle: boolean;
17
+ isPending: boolean;
18
+ isSuccess: boolean;
19
+ isError: boolean;
13
20
  }
14
- export declare const useMutation: <TArgs extends any[], TReturn>(opts: UseMutationOptions<TArgs, TReturn>) => UseMutationReturn<TArgs, TReturn>;
21
+ export declare const useMutation: <TVariables = void, TData = unknown>(options: UseMutationOptions<TVariables, TData>) => UseMutationReturn<TVariables, TData>;
15
22
  export {};
@@ -1,6 +1,15 @@
1
- type GenericObject = Record<string, any>;
2
- type Return<TState, TArgs = ((state: TState) => Partial<TState>) | Partial<TState>> = [TState, (arg: TArgs) => void, () => void];
3
- type MaybeReturn<TState> = Return<TState | undefined, ((state: TState | undefined) => Partial<TState>) | Partial<TState>>;
4
- export declare function useObject<T extends GenericObject>(): MaybeReturn<T>;
5
- export declare function useObject<T extends GenericObject>(initialValue: T): Return<T>;
6
- export {};
1
+ export interface UseObjectOptions<T> {
2
+ /** Called after every state change. NOT called on initial mount. */
3
+ onChange?: (state: T) => void;
4
+ }
5
+ export interface UseObjectActions<T> {
6
+ /** Shallow-merge a partial (or functional updater returning a partial). */
7
+ set(partial: Partial<T> | ((state: T) => Partial<T>)): void;
8
+ /** Replace the entire object (no merge). Functional variant receives prev. */
9
+ replace(value: T | ((state: T) => T)): void;
10
+ /** Restore the mount-time value (frozen ref). */
11
+ reset(): void;
12
+ /** Update a single typed key. */
13
+ setKey<K extends keyof T>(key: K, value: T[K]): void;
14
+ }
15
+ export declare function useObject<T extends object>(initialValue: T, options?: UseObjectOptions<T>): readonly [T, UseObjectActions<T>];
@@ -0,0 +1 @@
1
+ export * from './use-prevent-page-close';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shows the browser's native "Leave site?" confirmation when the user
3
+ * tries to close the tab or reload the page while `enabled` is `true`.
4
+ *
5
+ * Note: this only covers full-page unload (tab close / reload). It does
6
+ * NOT intercept SPA route changes — for that, combine with your router's
7
+ * navigation guard. The dialog text is controlled by the browser and
8
+ * cannot be customized.
9
+ */
10
+ export declare function usePreventPageClose(enabled: boolean): void;
@@ -1,14 +1,21 @@
1
- import { ReactNode } from 'react';
2
- interface Return<T = ReactNode> {
3
- currentStepIndex: number;
4
- step: T;
5
- steps: T[];
6
- isFirstStep: boolean;
7
- isLastStep: boolean;
8
- goTo: (i: number) => void;
1
+ export interface UseStepActions {
2
+ /** Advance one step. No-op at the last step. Stable reference. */
9
3
  next: () => void;
4
+ /** Go back one step. No-op at the first step. Stable reference. */
10
5
  back: () => void;
11
- findAndGo: (predicate: (item: T) => boolean) => void;
6
+ /** Jump to an index, clamped to [0, count - 1]. Stable reference. */
7
+ goTo: (index: number) => void;
8
+ /** Return to index 0. Stable reference. */
9
+ reset: () => void;
10
+ /** True when there is a next step to advance to. */
11
+ canGoNext: boolean;
12
+ /** True when there is a previous step to go back to. */
13
+ canGoBack: boolean;
14
+ /** True when the current index is the first step. */
15
+ isFirstStep: boolean;
16
+ /** True when the current index is the last step. */
17
+ isLastStep: boolean;
18
+ /** Ratio of progress in [0, 1]. 0 when count <= 1. */
19
+ progress: number;
12
20
  }
13
- export declare function useStep<T = ReactNode>(steps: T[], amountSteps?: number): Return<T>;
14
- export {};
21
+ export declare function useStep(count: number): [number, UseStepActions];
@@ -8,6 +8,16 @@ import { FieldProps, Form as LibraryForm } from '../components';
8
8
  *
9
9
  * - `data` is the typed, parsed value, or `null` when validation fails.
10
10
  * - `errors` is the flattened `fieldErrors` object (empty on success).
11
+ *
12
+ * Value conventions worth knowing when writing the schema (these hold whether
13
+ * or not you use Zod):
14
+ * - `DateInput` and `DatePicker` submit an **ISO date string** (`yyyy-MM-dd`),
15
+ * or `""` when empty. The format is locale-agnostic, sortable, and parseable
16
+ * by `new Date()` or any backend without a custom parser. The displayed text
17
+ * stays `dd/MM/yyyy` — display and value are different layers. To reformat,
18
+ * it is a plain split: `iso.split("-").reverse().join("-")` → `dd-MM-yyyy`.
19
+ * Avoid round-tripping through `new Date(iso)` + local getters (timezone
20
+ * shift); split the string or use `parseISO`.
11
21
  */
12
22
  export declare function parseFormValues<T extends z.ZodType>(schema: T, values: Record<string, unknown>): {
13
23
  data: z.infer<T> | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boxcustodia/library",
3
- "version": "2.0.0-alpha.19",
3
+ "version": "2.0.0-alpha.20",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -18,7 +18,11 @@ import { click } from "../../utils/tests";
18
18
  describe("AlertDialog composite", () => {
19
19
  it("renders title and description when open", () => {
20
20
  render(
21
- <AlertDialog open title="Custom title" description="Custom description" />,
21
+ <AlertDialog
22
+ open
23
+ title="Custom title"
24
+ description="Custom description"
25
+ />,
22
26
  );
23
27
 
24
28
  expect(screen.getByText("Custom title")).toBeInTheDocument();
@@ -46,8 +50,12 @@ describe("AlertDialog composite", () => {
46
50
  />,
47
51
  );
48
52
 
49
- expect(screen.getByRole("button", { name: "Mantener" })).toBeInTheDocument();
50
- expect(screen.getByRole("button", { name: "Eliminar" })).toBeInTheDocument();
53
+ expect(
54
+ screen.getByRole("button", { name: "Mantener" }),
55
+ ).toBeInTheDocument();
56
+ expect(
57
+ screen.getByRole("button", { name: "Eliminar" }),
58
+ ).toBeInTheDocument();
51
59
  });
52
60
 
53
61
  it("calls onClose when cancel button is clicked", () => {
@@ -97,9 +105,7 @@ describe("AlertDialog composite", () => {
97
105
  );
98
106
 
99
107
  click(screen.getByRole("button", { name: "Abrir" }));
100
- await waitFor(() =>
101
- expect(screen.getByText("Title")).toBeInTheDocument(),
102
- );
108
+ await waitFor(() => expect(screen.getByText("Title")).toBeInTheDocument());
103
109
 
104
110
  click(screen.getByRole("button", { name: "Confirmar" }));
105
111
 
@@ -204,9 +210,7 @@ describe("AlertDialog primitives", () => {
204
210
  setup();
205
211
 
206
212
  click(screen.getByRole("button", { name: "Abrir" }));
207
- await waitFor(() =>
208
- expect(screen.getByText("Title")).toBeInTheDocument(),
209
- );
213
+ await waitFor(() => expect(screen.getByText("Title")).toBeInTheDocument());
210
214
 
211
215
  click(screen.getByRole("button", { name: "Cancelar" }));
212
216
 
@@ -58,9 +58,7 @@ describe("Autocomplete composite", () => {
58
58
  it("renders readOnly when readOnly prop is set", () => {
59
59
  render(<Autocomplete items={items} readOnly placeholder="ReadOnly" />);
60
60
 
61
- expect(screen.getByPlaceholderText("ReadOnly")).toHaveAttribute(
62
- "readonly",
63
- );
61
+ expect(screen.getByPlaceholderText("ReadOnly")).toHaveAttribute("readonly");
64
62
  });
65
63
 
66
64
  it("renders the start addon when provided", () => {
@@ -115,11 +113,7 @@ describe("Autocomplete composite", () => {
115
113
 
116
114
  it("forwards controlled value.label to the input", () => {
117
115
  render(
118
- <Autocomplete
119
- items={items}
120
- value={items[2]}
121
- onValueChange={() => {}}
122
- />,
116
+ <Autocomplete items={items} value={items[2]} onValueChange={() => {}} />,
123
117
  );
124
118
 
125
119
  expect(screen.getByRole("combobox")).toHaveValue("Cherry");
@@ -174,9 +168,7 @@ describe("Autocomplete composite", () => {
174
168
  );
175
169
 
176
170
  await user.click(
177
- document.querySelector(
178
- '[data-slot="autocomplete-clear"]',
179
- ) as HTMLElement,
171
+ document.querySelector('[data-slot="autocomplete-clear"]') as HTMLElement,
180
172
  );
181
173
 
182
174
  // Clear emits "" (empty string), not null — the composite's `?? null` only
@@ -305,9 +297,7 @@ describe("Autocomplete composite", () => {
305
297
  it("forwards a custom filter function", async () => {
306
298
  const user = userEvent.setup();
307
299
  const filter = vi.fn(() => true);
308
- render(
309
- <Autocomplete items={items} filter={filter} placeholder="Filter" />,
310
- );
300
+ render(<Autocomplete items={items} filter={filter} placeholder="Filter" />);
311
301
 
312
302
  await user.click(screen.getByRole("combobox"));
313
303
  await user.type(screen.getByRole("combobox"), "a");
@@ -94,16 +94,13 @@ describe("Avatar composite", () => {
94
94
  ["md", "size-10", "text-sm"],
95
95
  ["lg", "size-14", "text-base"],
96
96
  ["xl", "size-20", "text-xl"],
97
- ] as const)(
98
- "applies size '%s' classes and data-size attribute",
99
- (size, sizeClass, textClass) => {
100
- render(<Avatar alt={personName} src={imageSrc} size={size} />);
97
+ ] as const)("applies size '%s' classes and data-size attribute", (size, sizeClass, textClass) => {
98
+ render(<Avatar alt={personName} src={imageSrc} size={size} />);
101
99
 
102
- const root = document.querySelector('[data-slot="avatar"]');
103
- expect(root).toHaveAttribute("data-size", size);
104
- expect(root).toHaveClass(sizeClass, textClass);
105
- },
106
- );
100
+ const root = document.querySelector('[data-slot="avatar"]');
101
+ expect(root).toHaveAttribute("data-size", size);
102
+ expect(root).toHaveClass(sizeClass, textClass);
103
+ });
107
104
 
108
105
  it("defaults size to md when omitted", () => {
109
106
  render(<Avatar alt={personName} src={imageSrc} />);
@@ -158,9 +155,7 @@ describe("Avatar composite", () => {
158
155
  // fallback is absent right after mount proves the prop is being honored.
159
156
  render(<Avatar alt={personName} src="" delay={500} />);
160
157
 
161
- expect(
162
- document.querySelector('[data-slot="avatar-fallback"]'),
163
- ).toBeNull();
158
+ expect(document.querySelector('[data-slot="avatar-fallback"]')).toBeNull();
164
159
  });
165
160
 
166
161
  it("spreads extra props onto the AvatarRoot element", () => {
@@ -67,16 +67,13 @@ describe("Button component", () => {
67
67
  ["success", "bg-success"],
68
68
  ["warning", "bg-warning"],
69
69
  ["link", "text-primary"],
70
- ] as const)(
71
- "applies variant '%s' classes and data-variant attribute",
72
- (variant, expectedClass) => {
73
- render(<Button variant={variant} />);
74
- const button = screen.getByRole("button");
70
+ ] as const)("applies variant '%s' classes and data-variant attribute", (variant, expectedClass) => {
71
+ render(<Button variant={variant} />);
72
+ const button = screen.getByRole("button");
75
73
 
76
- expect(button).toHaveAttribute("data-variant", variant);
77
- expect(button).toHaveClass(expectedClass);
78
- },
79
- );
74
+ expect(button).toHaveAttribute("data-variant", variant);
75
+ expect(button).toHaveClass(expectedClass);
76
+ });
80
77
 
81
78
  it.each([
82
79
  ["default", "h-8"],
@@ -224,14 +221,12 @@ describe("BaseButton loading behavior", () => {
224
221
  expect(screen.getByTestId("btn-loader")).toBeInTheDocument();
225
222
  });
226
223
 
227
- it("hides the content wrapper while loading via CSS hook", () => {
224
+ it("renders children alongside the loader while loading", () => {
228
225
  render(<BaseButton loading>Visible label</BaseButton>);
229
226
 
230
- const content = screen
231
- .getByRole("button")
232
- .querySelector("[data-content]");
233
- expect(content).not.toBeNull();
234
- expect(content).toHaveTextContent("Visible label");
227
+ const button = screen.getByRole("button");
228
+ expect(button).toHaveTextContent("Visible label");
229
+ expect(screen.getByTestId("btn-loader")).toBeInTheDocument();
235
230
  });
236
231
 
237
232
  it("forwards style and arbitrary props to the underlying button", () => {
@@ -14,23 +14,28 @@ const buttonVariants = cva(
14
14
  "disabled:pointer-events-none disabled:opacity-50",
15
15
  "aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
16
16
  "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
17
- "[&[data-loading]>[data-content]]:invisible",
17
+ "[&[data-loading]]:text-transparent",
18
+ "[&[data-loading]>*:not([data-loader])]:invisible",
18
19
  "[&[data-loading]]:pointer-events-none",
19
20
  ],
20
21
  {
21
22
  variants: {
22
23
  variant: {
23
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
24
+ default:
25
+ "bg-primary text-primary-foreground hover:bg-primary/90 [--btn-loader-color:var(--color-primary-foreground)]",
24
26
  outline:
25
- "border-border hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:hover:bg-input/50",
27
+ "border-border hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:hover:bg-input/50 [--btn-loader-color:var(--color-foreground)]",
26
28
  secondary:
27
- "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
29
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground [--btn-loader-color:var(--color-secondary-foreground)]",
28
30
  ghost:
29
- "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
30
- error: "bg-error text-error-foreground hover:bg-error/90",
31
- success: "bg-success text-success-foreground hover:bg-success/90",
32
- warning: "bg-warning text-warning-foreground hover:bg-warning/90",
33
- link: "text-primary underline-offset-4 hover:underline",
31
+ "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 [--btn-loader-color:var(--color-foreground)]",
32
+ error:
33
+ "bg-error text-error-foreground hover:bg-error/90 [--btn-loader-color:var(--color-error-foreground)]",
34
+ success:
35
+ "bg-success text-success-foreground hover:bg-success/90 [--btn-loader-color:var(--color-success-foreground)]",
36
+ warning:
37
+ "bg-warning text-warning-foreground hover:bg-warning/90 [--btn-loader-color:var(--color-warning-foreground)]",
38
+ link: "text-primary underline-offset-4 hover:underline [--btn-loader-color:var(--color-primary)]",
34
39
  },
35
40
  size: {
36
41
  default: "h-8 px-2.5",
@@ -45,14 +45,12 @@ export const BaseButton = ({
45
45
  onClick={handleClick}
46
46
  style={style}
47
47
  >
48
- <span data-content className="contents">
49
- {children}
50
- </span>
48
+ {children}
51
49
  {loading && (
52
50
  <LoaderCircle
53
51
  data-loader
54
52
  data-testid="btn-loader"
55
- className="absolute inset-0 m-auto size-4 animate-spin"
53
+ className="absolute inset-0 m-auto size-4 animate-spin text-[var(--btn-loader-color,currentColor)]"
56
54
  />
57
55
  )}
58
56
  </ButtonPrimitive>
@@ -7,7 +7,9 @@ describe("Calendar component", () => {
7
7
  it("renders the day-picker root with the calendar slot", () => {
8
8
  render(<Calendar mode="single" />);
9
9
 
10
- expect(document.querySelector('[data-slot="calendar"]')).toBeInTheDocument();
10
+ expect(
11
+ document.querySelector('[data-slot="calendar"]'),
12
+ ).toBeInTheDocument();
11
13
  });
12
14
 
13
15
  it("applies the cell-size variables and merges a custom className on root", () => {
@@ -29,10 +31,10 @@ describe("Calendar component", () => {
29
31
  it("renders a label caption (no dropdowns) with captionLayout='label'", () => {
30
32
  render(<Calendar mode="single" captionLayout="label" />);
31
33
 
34
+ expect(document.querySelector('[data-slot="select-trigger"]')).toBeNull();
32
35
  expect(
33
- document.querySelector('[data-slot="select-trigger"]'),
34
- ).toBeNull();
35
- expect(document.querySelector('[data-slot="calendar"]')).toBeInTheDocument();
36
+ document.querySelector('[data-slot="calendar"]'),
37
+ ).toBeInTheDocument();
36
38
  });
37
39
 
38
40
  it("renders previous and next navigation buttons (Chevron left/right)", () => {
@@ -48,10 +50,7 @@ describe("Calendar component", () => {
48
50
 
49
51
  it("merges a custom classNames entry onto the matching slot", () => {
50
52
  render(
51
- <Calendar
52
- mode="single"
53
- classNames={{ month: "custom-month-class" }}
54
- />,
53
+ <Calendar mode="single" classNames={{ month: "custom-month-class" }} />,
55
54
  );
56
55
 
57
56
  const month = document.querySelector(".custom-month-class");
@@ -117,22 +116,18 @@ describe("Calendar component", () => {
117
116
  />,
118
117
  );
119
118
 
120
- expect(document.querySelector('[data-slot="calendar"]')).toBeInTheDocument();
119
+ expect(
120
+ document.querySelector('[data-slot="calendar"]'),
121
+ ).toBeInTheDocument();
121
122
  });
122
123
 
123
124
  it("merges user-provided components over the defaults", () => {
124
125
  const CustomChevron = () => <span data-testid="custom-chevron" />;
125
- render(
126
- <Calendar
127
- mode="single"
128
- components={{ Chevron: CustomChevron }}
129
- />,
130
- );
126
+ render(<Calendar mode="single" components={{ Chevron: CustomChevron }} />);
131
127
 
132
128
  expect(screen.getAllByTestId("custom-chevron").length).toBeGreaterThan(0);
133
129
  });
134
130
 
135
-
136
131
  it("formats the month dropdown labels in Spanish (short form)", () => {
137
132
  render(
138
133
  <Calendar
@@ -143,9 +138,7 @@ describe("Calendar component", () => {
143
138
  );
144
139
 
145
140
  // January in es short form is "ene".
146
- const monthTrigger = document.querySelector(
147
- '[data-slot="select-trigger"]',
148
- );
141
+ const monthTrigger = document.querySelector('[data-slot="select-trigger"]');
149
142
  expect(monthTrigger).not.toBeNull();
150
143
  expect(monthTrigger?.textContent?.toLowerCase()).toContain("ene");
151
144
  });
@@ -33,6 +33,10 @@ function CalendarDropdown({
33
33
  <Select
34
34
  items={items}
35
35
  value={selected}
36
+ // Month/year dropdowns are calendar navigation, not form fields. Force
37
+ // off the invalid state so a surrounding invalid Field never paints them
38
+ // with the error border.
39
+ aria-invalid={false}
36
40
  className="py-1 h-7"
37
41
  getLabel={(o) => o.label}
38
42
  getId={(o) => String(o.value)}
@@ -67,9 +67,7 @@ describe("Card composite", () => {
67
67
 
68
68
  expect(document.querySelector('[data-slot="card-header"]')).not.toBeNull();
69
69
  expect(document.querySelector('[data-slot="card-title"]')).toBeNull();
70
- expect(
71
- document.querySelector('[data-slot="card-description"]'),
72
- ).toBeNull();
70
+ expect(document.querySelector('[data-slot="card-description"]')).toBeNull();
73
71
  const action = document.querySelector('[data-slot="card-action"]');
74
72
  expect(action).toHaveTextContent("Go");
75
73
  });
@@ -101,9 +99,9 @@ describe("Card composite", () => {
101
99
  </Card>,
102
100
  );
103
101
 
104
- expect(document.querySelector('[data-slot="card-title"]')).toHaveTextContent(
105
- "Title",
106
- );
102
+ expect(
103
+ document.querySelector('[data-slot="card-title"]'),
104
+ ).toHaveTextContent("Title");
107
105
  expect(
108
106
  document.querySelector('[data-slot="card-description"]'),
109
107
  ).toHaveTextContent("Description");
@@ -110,16 +110,18 @@ describe("Checkbox (single composite)", () => {
110
110
  it("reverses the layout when controlFirst is false", () => {
111
111
  render(<Checkbox label="Reversed" controlFirst={false} />);
112
112
 
113
- const wrapper = document.querySelector('[data-slot="checkbox"]')
114
- ?.parentElement;
113
+ const wrapper = document.querySelector(
114
+ '[data-slot="checkbox"]',
115
+ )?.parentElement;
115
116
  expect(wrapper).toHaveClass("flex-row-reverse");
116
117
  });
117
118
 
118
119
  it("does not reverse the layout by default", () => {
119
120
  render(<Checkbox label="Default order" />);
120
121
 
121
- const wrapper = document.querySelector('[data-slot="checkbox"]')
122
- ?.parentElement;
122
+ const wrapper = document.querySelector(
123
+ '[data-slot="checkbox"]',
124
+ )?.parentElement;
123
125
  expect(wrapper).not.toHaveClass("flex-row-reverse");
124
126
  });
125
127
 
@@ -212,8 +214,9 @@ describe("Checkbox.Item", () => {
212
214
  </CheckboxGroupContext.Provider>,
213
215
  );
214
216
 
215
- const wrapper = document.querySelector('[data-slot="checkbox"]')
216
- ?.parentElement;
217
+ const wrapper = document.querySelector(
218
+ '[data-slot="checkbox"]',
219
+ )?.parentElement;
217
220
  expect(wrapper).toHaveClass("flex-row-reverse");
218
221
  });
219
222
 
@@ -348,8 +351,9 @@ describe("Checkbox.Group", () => {
348
351
  </Checkbox.Group>,
349
352
  );
350
353
 
351
- const wrapper = document.querySelector('[data-slot="checkbox"]')
352
- ?.parentElement;
354
+ const wrapper = document.querySelector(
355
+ '[data-slot="checkbox"]',
356
+ )?.parentElement;
353
357
  expect(wrapper).toHaveClass("flex-row-reverse");
354
358
  });
355
359
 
@@ -60,9 +60,7 @@ describe("CheckboxGroup composite", () => {
60
60
  it("does not render a legend when omitted", () => {
61
61
  render(<CheckboxGroup items={options} />);
62
62
 
63
- expect(
64
- document.querySelector('[data-slot="fieldset-legend"]'),
65
- ).toBeNull();
63
+ expect(document.querySelector('[data-slot="fieldset-legend"]')).toBeNull();
66
64
  });
67
65
 
68
66
  it("fires onValueChange when an item is toggled", async () => {
@@ -109,8 +107,9 @@ describe("CheckboxGroup composite", () => {
109
107
  </CheckboxGroup>,
110
108
  );
111
109
 
112
- const wrapper = document.querySelector('[data-slot="checkbox"]')
113
- ?.parentElement;
110
+ const wrapper = document.querySelector(
111
+ '[data-slot="checkbox"]',
112
+ )?.parentElement;
114
113
  expect(wrapper).toHaveClass("flex-row-reverse");
115
114
  });
116
115
 
@@ -149,8 +148,8 @@ describe("CheckboxGroup composite", () => {
149
148
  );
150
149
 
151
150
  // The invalid field state flows into the items as data-invalid.
152
- expect(
153
- screen.getByRole("checkbox", { name: "Option A" }),
154
- ).toHaveAttribute("data-invalid");
151
+ expect(screen.getByRole("checkbox", { name: "Option A" })).toHaveAttribute(
152
+ "data-invalid",
153
+ );
155
154
  });
156
155
  });
@@ -54,7 +54,11 @@ describe("Combobox (single mode)", () => {
54
54
  it("fires onValueChange with the selected item object", async () => {
55
55
  const onValueChange = vi.fn();
56
56
  render(
57
- <Combobox items={items} placeholder="Pick" onValueChange={onValueChange} />,
57
+ <Combobox
58
+ items={items}
59
+ placeholder="Pick"
60
+ onValueChange={onValueChange}
61
+ />,
58
62
  );
59
63
 
60
64
  const input = getInput();
@@ -223,14 +227,20 @@ describe("Combobox (multiple mode)", () => {
223
227
  );
224
228
 
225
229
  const chips = document.querySelectorAll('[data-slot="combobox-chip"]');
226
- expect(
227
- [...chips].map((c) => c.getAttribute("aria-label")),
228
- ).toEqual(["Apple", "Banana"]);
230
+ expect([...chips].map((c) => c.getAttribute("aria-label"))).toEqual([
231
+ "Apple",
232
+ "Banana",
233
+ ]);
229
234
  });
230
235
 
231
236
  it("renders the chips container and a chips search input", () => {
232
237
  render(
233
- <Combobox multiple items={items} placeholder="Search" defaultValue={[]} />,
238
+ <Combobox
239
+ multiple
240
+ items={items}
241
+ placeholder="Search"
242
+ defaultValue={[]}
243
+ />,
234
244
  );
235
245
 
236
246
  expect(
@@ -248,9 +258,7 @@ describe("Combobox (multiple mode)", () => {
248
258
  />,
249
259
  );
250
260
 
251
- expect(
252
- screen.getByRole("button", { name: "Quitar" }),
253
- ).toBeInTheDocument();
261
+ expect(screen.getByRole("button", { name: "Quitar" })).toBeInTheDocument();
254
262
  });
255
263
 
256
264
  it("fires onValueChange when selecting an option", async () => {
@@ -304,10 +312,9 @@ describe("Combobox Field integration", () => {
304
312
  </Field>,
305
313
  );
306
314
 
307
- expect(document.querySelector('[data-slot="combobox-chips"]')).toHaveAttribute(
308
- "aria-invalid",
309
- "true",
310
- );
315
+ expect(
316
+ document.querySelector('[data-slot="combobox-chips"]'),
317
+ ).toHaveAttribute("aria-invalid", "true");
311
318
  });
312
319
 
313
320
  it("does not set aria-invalid when standalone", () => {
@@ -384,12 +391,8 @@ describe("Combobox escape-hatch primitives", () => {
384
391
  expect(
385
392
  document.querySelector('[data-slot="combobox-input"]'),
386
393
  ).toBeInTheDocument();
387
- expect(
388
- document.querySelector('[data-slot="combobox-trigger"]'),
389
- ).toBeNull();
390
- expect(
391
- document.querySelector('[data-slot="combobox-clear"]'),
392
- ).toBeNull();
394
+ expect(document.querySelector('[data-slot="combobox-trigger"]')).toBeNull();
395
+ expect(document.querySelector('[data-slot="combobox-clear"]')).toBeNull();
393
396
  });
394
397
 
395
398
  it("renders a select trigger with a clear control when showClear", () => {
@@ -448,9 +451,9 @@ describe("Combobox escape-hatch primitives", () => {
448
451
  </ComboboxRoot>,
449
452
  );
450
453
 
451
- expect(
452
- document.querySelector('[data-slot="combobox-group"]'),
453
- ).toHaveClass("grp-cls");
454
+ expect(document.querySelector('[data-slot="combobox-group"]')).toHaveClass(
455
+ "grp-cls",
456
+ );
454
457
  expect(
455
458
  document.querySelector('[data-slot="combobox-group-label"]'),
456
459
  ).toHaveTextContent("Fruits");