@g4rcez/components 5.0.1 → 5.0.2

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 (307) hide show
  1. package/dist/components/core/button.d.ts +77 -0
  2. package/dist/components/core/button.d.ts.map +1 -0
  3. package/dist/components/core/button.jsx +79 -0
  4. package/dist/components/core/heading.d.ts +3 -0
  5. package/dist/components/core/heading.d.ts.map +1 -0
  6. package/dist/components/core/heading.jsx +4 -0
  7. package/dist/components/core/polymorph.d.ts +10 -0
  8. package/dist/components/core/polymorph.d.ts.map +1 -0
  9. package/dist/components/core/polymorph.jsx +5 -0
  10. package/dist/components/core/render-on-view.d.ts +7 -0
  11. package/dist/components/core/render-on-view.d.ts.map +1 -0
  12. package/dist/components/core/render-on-view.jsx +31 -0
  13. package/dist/components/core/resizable.d.ts +3 -0
  14. package/dist/components/core/resizable.d.ts.map +1 -0
  15. package/dist/components/core/resizable.jsx +51 -0
  16. package/dist/components/core/slot.d.ts +16 -0
  17. package/dist/components/core/slot.d.ts.map +1 -0
  18. package/dist/components/core/slot.jsx +156 -0
  19. package/dist/components/core/tag.d.ts +35 -0
  20. package/dist/components/core/tag.d.ts.map +1 -0
  21. package/dist/components/core/tag.jsx +53 -0
  22. package/dist/components/core/typography.d.ts +25 -0
  23. package/dist/components/core/typography.d.ts.map +1 -0
  24. package/dist/components/core/typography.jsx +20 -0
  25. package/dist/components/display/alert.d.ts +28 -0
  26. package/dist/components/display/alert.d.ts.map +1 -0
  27. package/dist/components/display/alert.jsx +61 -0
  28. package/dist/components/display/calendar.d.ts +42 -0
  29. package/dist/components/display/calendar.d.ts.map +1 -0
  30. package/dist/components/display/calendar.jsx +318 -0
  31. package/dist/components/display/card.d.ts +29 -0
  32. package/dist/components/display/card.d.ts.map +1 -0
  33. package/dist/components/display/card.jsx +43 -0
  34. package/dist/components/display/empty.d.ts +8 -0
  35. package/dist/components/display/empty.d.ts.map +1 -0
  36. package/dist/components/display/empty.jsx +11 -0
  37. package/dist/components/display/list.d.ts +16 -0
  38. package/dist/components/display/list.d.ts.map +1 -0
  39. package/dist/components/display/list.jsx +85 -0
  40. package/dist/components/display/notifications.d.ts +27 -0
  41. package/dist/components/display/notifications.d.ts.map +1 -0
  42. package/dist/components/display/notifications.jsx +130 -0
  43. package/dist/components/display/progress.d.ts +16 -0
  44. package/dist/components/display/progress.d.ts.map +1 -0
  45. package/dist/components/display/progress.jsx +21 -0
  46. package/dist/components/display/shortcut.d.ts +4 -0
  47. package/dist/components/display/shortcut.d.ts.map +1 -0
  48. package/dist/components/display/shortcut.jsx +23 -0
  49. package/dist/components/display/skeleton.d.ts +12 -0
  50. package/dist/components/display/skeleton.d.ts.map +1 -0
  51. package/dist/components/display/skeleton.jsx +19 -0
  52. package/dist/components/display/spinner.d.ts +5 -0
  53. package/dist/components/display/spinner.d.ts.map +1 -0
  54. package/dist/components/display/spinner.jsx +11 -0
  55. package/dist/components/display/stats.d.ts +12 -0
  56. package/dist/components/display/stats.d.ts.map +1 -0
  57. package/dist/components/display/stats.jsx +16 -0
  58. package/dist/components/display/step.d.ts +24 -0
  59. package/dist/components/display/step.d.ts.map +1 -0
  60. package/dist/components/display/step.jsx +145 -0
  61. package/dist/components/display/tabs.d.ts +24 -0
  62. package/dist/components/display/tabs.d.ts.map +1 -0
  63. package/dist/components/display/tabs.jsx +125 -0
  64. package/dist/components/display/timeline.d.ts +10 -0
  65. package/dist/components/display/timeline.d.ts.map +1 -0
  66. package/dist/components/display/timeline.jsx +25 -0
  67. package/dist/components/floating/command-palette.d.ts +49 -0
  68. package/dist/components/floating/command-palette.d.ts.map +1 -0
  69. package/dist/components/floating/command-palette.jsx +223 -0
  70. package/dist/components/floating/dropdown.d.ts +15 -0
  71. package/dist/components/floating/dropdown.d.ts.map +1 -0
  72. package/dist/components/floating/dropdown.jsx +56 -0
  73. package/dist/components/floating/expand.d.ts +11 -0
  74. package/dist/components/floating/expand.d.ts.map +1 -0
  75. package/dist/components/floating/expand.jsx +44 -0
  76. package/dist/components/floating/menu.d.ts +52 -0
  77. package/dist/components/floating/menu.d.ts.map +1 -0
  78. package/dist/components/floating/menu.jsx +165 -0
  79. package/dist/components/floating/modal.d.ts +60 -0
  80. package/dist/components/floating/modal.d.ts.map +1 -0
  81. package/dist/components/floating/modal.jsx +336 -0
  82. package/dist/components/floating/toolbar.d.ts +6 -0
  83. package/dist/components/floating/toolbar.d.ts.map +1 -0
  84. package/dist/components/floating/toolbar.jsx +5 -0
  85. package/dist/components/floating/tooltip.d.ts +17 -0
  86. package/dist/components/floating/tooltip.d.ts.map +1 -0
  87. package/dist/components/floating/tooltip.jsx +67 -0
  88. package/dist/components/floating/wizard.d.ts +26 -0
  89. package/dist/components/floating/wizard.d.ts.map +1 -0
  90. package/dist/components/floating/wizard.jsx +165 -0
  91. package/dist/components/form/autocomplete.d.ts +16 -0
  92. package/dist/components/form/autocomplete.d.ts.map +1 -0
  93. package/dist/components/form/autocomplete.jsx +290 -0
  94. package/dist/components/form/checkbox.d.ts +12 -0
  95. package/dist/components/form/checkbox.d.ts.map +1 -0
  96. package/dist/components/form/checkbox.jsx +12 -0
  97. package/dist/components/form/date-picker.d.ts +10 -0
  98. package/dist/components/form/date-picker.d.ts.map +1 -0
  99. package/dist/components/form/date-picker.jsx +115 -0
  100. package/dist/components/form/file-upload.d.ts +15 -0
  101. package/dist/components/form/file-upload.d.ts.map +1 -0
  102. package/dist/components/form/file-upload.jsx +138 -0
  103. package/dist/components/form/form.d.ts +3 -0
  104. package/dist/components/form/form.d.ts.map +1 -0
  105. package/dist/components/form/form.jsx +10 -0
  106. package/dist/components/form/formReset.d.ts +2 -0
  107. package/dist/components/form/formReset.d.ts.map +1 -0
  108. package/dist/components/form/formReset.jsx +17 -0
  109. package/dist/components/form/free-text.d.ts +11 -0
  110. package/dist/components/form/free-text.d.ts.map +1 -0
  111. package/dist/components/form/free-text.jsx +41 -0
  112. package/dist/components/form/input-field.d.ts +34 -0
  113. package/dist/components/form/input-field.d.ts.map +1 -0
  114. package/dist/components/form/input-field.jsx +58 -0
  115. package/dist/components/form/input.d.ts +52 -0
  116. package/dist/components/form/input.d.ts.map +1 -0
  117. package/dist/components/form/input.jsx +36 -0
  118. package/dist/components/form/multi-select.d.ts +19 -0
  119. package/dist/components/form/multi-select.d.ts.map +1 -0
  120. package/dist/components/form/multi-select.jsx +344 -0
  121. package/dist/components/form/radiobox.d.ts +7 -0
  122. package/dist/components/form/radiobox.d.ts.map +1 -0
  123. package/dist/components/form/radiobox.jsx +6 -0
  124. package/dist/components/form/select.d.ts +13 -0
  125. package/dist/components/form/select.d.ts.map +1 -0
  126. package/dist/components/form/select.jsx +44 -0
  127. package/dist/components/form/slider.d.ts +7 -0
  128. package/dist/components/form/slider.d.ts.map +1 -0
  129. package/dist/components/form/slider.jsx +45 -0
  130. package/dist/components/form/switch.d.ts +9 -0
  131. package/dist/components/form/switch.d.ts.map +1 -0
  132. package/dist/components/form/switch.jsx +46 -0
  133. package/dist/components/form/task-list.d.ts +3 -0
  134. package/dist/components/form/task-list.d.ts.map +1 -0
  135. package/dist/components/form/task-list.jsx +26 -0
  136. package/dist/components/form/textarea.d.ts +5 -0
  137. package/dist/components/form/textarea.d.ts.map +1 -0
  138. package/dist/components/form/textarea.jsx +26 -0
  139. package/dist/components/index.d.ts +45 -0
  140. package/dist/components/index.d.ts.map +1 -0
  141. package/dist/components/index.js +44 -0
  142. package/dist/components/page-calendar/calendar-header.d.ts +16 -0
  143. package/dist/components/page-calendar/calendar-header.d.ts.map +1 -0
  144. package/dist/components/page-calendar/calendar-header.jsx +83 -0
  145. package/dist/components/page-calendar/day-view.d.ts +12 -0
  146. package/dist/components/page-calendar/day-view.d.ts.map +1 -0
  147. package/dist/components/page-calendar/day-view.jsx +89 -0
  148. package/dist/components/page-calendar/event-pill.d.ts +9 -0
  149. package/dist/components/page-calendar/event-pill.d.ts.map +1 -0
  150. package/dist/components/page-calendar/event-pill.jsx +25 -0
  151. package/dist/components/page-calendar/index.d.ts +4 -0
  152. package/dist/components/page-calendar/index.d.ts.map +1 -0
  153. package/dist/components/page-calendar/index.js +2 -0
  154. package/dist/components/page-calendar/month-view.d.ts +11 -0
  155. package/dist/components/page-calendar/month-view.d.ts.map +1 -0
  156. package/dist/components/page-calendar/month-view.jsx +46 -0
  157. package/dist/components/page-calendar/page-calendar.d.ts +18 -0
  158. package/dist/components/page-calendar/page-calendar.d.ts.map +1 -0
  159. package/dist/components/page-calendar/page-calendar.jsx +41 -0
  160. package/dist/components/page-calendar/page-calendar.types.d.ts +18 -0
  161. package/dist/components/page-calendar/page-calendar.types.d.ts.map +1 -0
  162. package/dist/components/page-calendar/page-calendar.types.js +1 -0
  163. package/dist/components/page-calendar/page-calendar.utils.d.ts +24 -0
  164. package/dist/components/page-calendar/page-calendar.utils.d.ts.map +1 -0
  165. package/dist/components/page-calendar/page-calendar.utils.js +93 -0
  166. package/dist/components/page-calendar/week-view.d.ts +11 -0
  167. package/dist/components/page-calendar/week-view.d.ts.map +1 -0
  168. package/dist/components/page-calendar/week-view.jsx +66 -0
  169. package/dist/components/table/filter.d.ts +42 -0
  170. package/dist/components/table/filter.d.ts.map +1 -0
  171. package/dist/components/table/filter.jsx +169 -0
  172. package/dist/components/table/group.d.ts +17 -0
  173. package/dist/components/table/group.d.ts.map +1 -0
  174. package/dist/components/table/group.jsx +75 -0
  175. package/dist/components/table/index.d.ts +19 -0
  176. package/dist/components/table/index.d.ts.map +1 -0
  177. package/dist/components/table/index.jsx +63 -0
  178. package/dist/components/table/inner-table.d.ts +29 -0
  179. package/dist/components/table/inner-table.d.ts.map +1 -0
  180. package/dist/components/table/inner-table.jsx +102 -0
  181. package/dist/components/table/metadata.d.ts +4 -0
  182. package/dist/components/table/metadata.d.ts.map +1 -0
  183. package/dist/components/table/metadata.jsx +36 -0
  184. package/dist/components/table/pagination.d.ts +5 -0
  185. package/dist/components/table/pagination.d.ts.map +1 -0
  186. package/dist/components/table/pagination.jsx +74 -0
  187. package/dist/components/table/row.d.ts +11 -0
  188. package/dist/components/table/row.d.ts.map +1 -0
  189. package/dist/components/table/row.jsx +49 -0
  190. package/dist/components/table/sort.d.ts +28 -0
  191. package/dist/components/table/sort.d.ts.map +1 -0
  192. package/dist/components/table/sort.jsx +109 -0
  193. package/dist/components/table/table-lib.d.ts +135 -0
  194. package/dist/components/table/table-lib.d.ts.map +1 -0
  195. package/dist/components/table/table-lib.js +83 -0
  196. package/dist/components/table/table.context.d.ts +10 -0
  197. package/dist/components/table/table.context.d.ts.map +1 -0
  198. package/dist/components/table/table.context.jsx +5 -0
  199. package/dist/components/table/thead.d.ts +9 -0
  200. package/dist/components/table/thead.d.ts.map +1 -0
  201. package/dist/components/table/thead.jsx +103 -0
  202. package/dist/config/context.d.ts +21 -0
  203. package/dist/config/context.d.ts.map +1 -0
  204. package/dist/config/context.js +12 -0
  205. package/dist/config/default-translations.d.ts +94 -0
  206. package/dist/config/default-translations.d.ts.map +1 -0
  207. package/dist/config/default-translations.jsx +87 -0
  208. package/dist/config/default-tweaks.d.ts +13 -0
  209. package/dist/config/default-tweaks.d.ts.map +1 -0
  210. package/dist/config/default-tweaks.js +4 -0
  211. package/dist/constants.d.ts +3 -0
  212. package/dist/constants.d.ts.map +1 -0
  213. package/dist/constants.js +2 -0
  214. package/dist/hooks/use-click-outside.d.ts +3 -0
  215. package/dist/hooks/use-click-outside.d.ts.map +1 -0
  216. package/dist/hooks/use-click-outside.js +17 -0
  217. package/dist/hooks/use-color-parser.d.ts +2 -0
  218. package/dist/hooks/use-color-parser.d.ts.map +1 -0
  219. package/dist/hooks/use-color-parser.js +9 -0
  220. package/dist/hooks/use-components-provider.d.ts +15 -0
  221. package/dist/hooks/use-components-provider.d.ts.map +1 -0
  222. package/dist/hooks/use-components-provider.jsx +22 -0
  223. package/dist/hooks/use-debounce.d.ts +5 -0
  224. package/dist/hooks/use-debounce.d.ts.map +1 -0
  225. package/dist/hooks/use-debounce.js +12 -0
  226. package/dist/hooks/use-floating-ref.d.ts +2 -0
  227. package/dist/hooks/use-floating-ref.d.ts.map +1 -0
  228. package/dist/hooks/use-floating-ref.js +6 -0
  229. package/dist/hooks/use-form.d.ts +394 -0
  230. package/dist/hooks/use-form.d.ts.map +1 -0
  231. package/dist/hooks/use-form.js +563 -0
  232. package/dist/hooks/use-hover.d.ts +3 -0
  233. package/dist/hooks/use-hover.d.ts.map +1 -0
  234. package/dist/hooks/use-hover.js +18 -0
  235. package/dist/hooks/use-input-id.d.ts +4 -0
  236. package/dist/hooks/use-input-id.d.ts.map +1 -0
  237. package/dist/hooks/use-input-id.js +5 -0
  238. package/dist/hooks/use-is-coarse-device.d.ts +2 -0
  239. package/dist/hooks/use-is-coarse-device.d.ts.map +1 -0
  240. package/dist/hooks/use-is-coarse-device.js +12 -0
  241. package/dist/hooks/use-locale.d.ts +3 -0
  242. package/dist/hooks/use-locale.d.ts.map +1 -0
  243. package/dist/hooks/use-locale.js +10 -0
  244. package/dist/hooks/use-media-query.d.ts +2 -0
  245. package/dist/hooks/use-media-query.d.ts.map +1 -0
  246. package/dist/hooks/use-media-query.js +25 -0
  247. package/dist/hooks/use-on-event.d.ts +4 -0
  248. package/dist/hooks/use-on-event.d.ts.map +1 -0
  249. package/dist/hooks/use-on-event.js +10 -0
  250. package/dist/hooks/use-parent.d.ts +3 -0
  251. package/dist/hooks/use-parent.d.ts.map +1 -0
  252. package/dist/hooks/use-parent.js +21 -0
  253. package/dist/hooks/use-preferences.d.ts +2 -0
  254. package/dist/hooks/use-preferences.d.ts.map +1 -0
  255. package/dist/hooks/use-preferences.js +23 -0
  256. package/dist/hooks/use-previous.d.ts +2 -0
  257. package/dist/hooks/use-previous.d.ts.map +1 -0
  258. package/dist/hooks/use-previous.js +9 -0
  259. package/dist/hooks/use-reactive.d.ts +2 -0
  260. package/dist/hooks/use-reactive.d.ts.map +1 -0
  261. package/dist/hooks/use-reactive.js +9 -0
  262. package/dist/hooks/use-remove-scroll.d.ts +4 -0
  263. package/dist/hooks/use-remove-scroll.d.ts.map +1 -0
  264. package/dist/hooks/use-remove-scroll.js +48 -0
  265. package/dist/hooks/use-resize-observer.d.ts +2 -0
  266. package/dist/hooks/use-resize-observer.d.ts.map +1 -0
  267. package/dist/hooks/use-resize-observer.js +17 -0
  268. package/dist/hooks/use-stable-ref.d.ts +2 -0
  269. package/dist/hooks/use-stable-ref.d.ts.map +1 -0
  270. package/dist/hooks/use-stable-ref.js +9 -0
  271. package/dist/hooks/use-swipe.d.ts +8 -0
  272. package/dist/hooks/use-swipe.d.ts.map +1 -0
  273. package/dist/hooks/use-swipe.js +17 -0
  274. package/dist/hooks/use-translations.d.ts +92 -0
  275. package/dist/hooks/use-translations.d.ts.map +1 -0
  276. package/dist/hooks/use-translations.js +9 -0
  277. package/dist/hooks/use-tweaks.d.ts +3 -0
  278. package/dist/hooks/use-tweaks.d.ts.map +1 -0
  279. package/dist/hooks/use-tweaks.js +9 -0
  280. package/dist/hooks/use-window-size.d.ts +5 -0
  281. package/dist/hooks/use-window-size.d.ts.map +1 -0
  282. package/dist/hooks/use-window-size.js +14 -0
  283. package/dist/index.d.ts +22 -0
  284. package/dist/index.d.ts.map +1 -0
  285. package/dist/index.js +20 -7932
  286. package/dist/lib/combi-keys.d.ts +15 -0
  287. package/dist/lib/combi-keys.d.ts.map +1 -0
  288. package/dist/lib/combi-keys.js +60 -0
  289. package/dist/lib/dict.d.ts +9 -0
  290. package/dist/lib/dict.d.ts.map +1 -0
  291. package/dist/lib/dict.js +28 -0
  292. package/dist/lib/dom.d.ts +20 -0
  293. package/dist/lib/dom.d.ts.map +1 -0
  294. package/dist/lib/dom.js +185 -0
  295. package/dist/lib/fns.d.ts +11 -0
  296. package/dist/lib/fns.d.ts.map +1 -0
  297. package/dist/lib/fns.js +46 -0
  298. package/dist/lib/fzf.d.ts +16 -0
  299. package/dist/lib/fzf.d.ts.map +1 -0
  300. package/dist/lib/fzf.js +115 -0
  301. package/dist/lib/keyboard-area.d.ts +16 -0
  302. package/dist/lib/keyboard-area.d.ts.map +1 -0
  303. package/dist/lib/keyboard-area.js +14 -0
  304. package/dist/types.d.ts +26 -0
  305. package/dist/types.d.ts.map +1 -0
  306. package/dist/types.js +1 -0
  307. package/package.json +1 -1
@@ -0,0 +1,563 @@
1
+ "use client";
2
+ import { isValid } from "date-fns";
3
+ import { parse } from "qs";
4
+ import { useCallback, useEffect, useRef, useState } from "react";
5
+ import { getPath, Is } from "sidekicker";
6
+ import { LocalStorage } from "storage-manager-js";
7
+ import { z, ZodNumber } from "zod";
8
+ import { formReset, } from "../components";
9
+ /**
10
+ * Validates if a value is valid JSON
11
+ * @param value - The value to validate
12
+ * @returns True if the value is valid JSON
13
+ * @internal
14
+ */
15
+ const isValidJSON = (value) => {
16
+ let str;
17
+ if (typeof value === "string") {
18
+ str = value;
19
+ }
20
+ else {
21
+ try {
22
+ str = JSON.stringify(value);
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ try {
29
+ JSON.parse(str);
30
+ return true;
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ };
36
+ const convertPath = (path) => path.replace(/\[(\d+)]/g, ".$1").split(".");
37
+ const shallowSetPath = (obj, keys, value) => {
38
+ if (keys.length === 0)
39
+ return value;
40
+ const [key, ...rest] = keys;
41
+ const current = obj !== null ? obj[key] : undefined;
42
+ const nextKey = rest[0];
43
+ const fallback = nextKey !== undefined && !Number.isNaN(Number(nextKey)) ? [] : {};
44
+ const updated = shallowSetPath(current ?? fallback, rest, value);
45
+ if (Array.isArray(obj)) {
46
+ const clone = obj.slice();
47
+ clone[Number(key)] = updated;
48
+ return clone;
49
+ }
50
+ return { ...(obj ?? {}), [key]: updated };
51
+ };
52
+ const setPath = (o, path, value) => {
53
+ const pathArr = Array.isArray(path) ? path.map(String) : convertPath(path);
54
+ return shallowSetPath(o, pathArr, value);
55
+ };
56
+ const sort = (a, b) => a.localeCompare(b);
57
+ const getDefaultValue = (inner) => {
58
+ const instanceName = inner._def.typeName;
59
+ if (instanceName === "ZodDefault")
60
+ return inner._def.defaultValue();
61
+ if (inner instanceof z.ZodObject)
62
+ return getDefaults(inner);
63
+ if (instanceName === "ZodArray")
64
+ return [];
65
+ if ("innerType" in inner._def) {
66
+ const defaults = getDefaultValue(inner._def.innerType);
67
+ if (instanceName === "ZodArray")
68
+ return defaults ?? [];
69
+ return defaults;
70
+ }
71
+ return undefined;
72
+ };
73
+ const getDefaults = (schema) => Object.fromEntries(Object.entries(schema.shape).map(([key, value]) => {
74
+ return [key, getDefaultValue(value)];
75
+ }));
76
+ const deepMerge = (a, b) => {
77
+ // as unknown as Record: structuredClone returns T, but we mutate it dynamically; static T & U proven at return
78
+ const result = structuredClone(a);
79
+ for (const key in b) {
80
+ const bValue = b[key];
81
+ const aValue = result[key];
82
+ if (bValue !== undefined) {
83
+ if (typeof bValue === "object" &&
84
+ bValue !== null &&
85
+ !Array.isArray(bValue) &&
86
+ typeof aValue === "object" &&
87
+ aValue !== null &&
88
+ !Array.isArray(aValue)) {
89
+ result[key] = deepMerge(aValue, bValue);
90
+ }
91
+ else {
92
+ result[key] = bValue ?? aValue;
93
+ }
94
+ }
95
+ }
96
+ return result;
97
+ };
98
+ const options = {
99
+ sort,
100
+ allowDots: true,
101
+ charset: "utf-8",
102
+ parseArrays: true,
103
+ plainObjects: true,
104
+ charsetSentinel: true,
105
+ allowPrototypes: false,
106
+ depth: Number.MAX_SAFE_INTEGER,
107
+ arrayLimit: Number.MAX_SAFE_INTEGER,
108
+ parameterLimit: Number.MAX_SAFE_INTEGER,
109
+ };
110
+ /**
111
+ * Converts a form element to a JSON object
112
+ * @param form - The HTML form element to convert
113
+ * @returns A JSON object representing the form data
114
+ */
115
+ export const formToJson = (form) => {
116
+ const formData = new FormData(form);
117
+ const urlSearchParams = new URLSearchParams(Array.from(formData.entries()).filter((entry) => typeof entry[1] === "string"));
118
+ return parse(urlSearchParams.toString(), options);
119
+ };
120
+ const schemaShapeCache = new WeakMap();
121
+ export const getSchemaShape = (name, schema) => {
122
+ let nameMap = schemaShapeCache.get(schema);
123
+ if (!nameMap) {
124
+ nameMap = new Map();
125
+ schemaShapeCache.set(schema, nameMap);
126
+ }
127
+ const cached = nameMap.get(name);
128
+ if (cached !== undefined)
129
+ return cached;
130
+ const result = convertPath(name).reduce((acc, el) => {
131
+ if (el === "")
132
+ return acc;
133
+ const zodObj = acc;
134
+ const shape = zodObj.shape?.[el] || acc;
135
+ const result = shape._def.typeName === "ZodArray" ? shape.element : shape;
136
+ return result;
137
+ }, schema);
138
+ nameMap.set(name, result);
139
+ return result;
140
+ };
141
+ const getValueByType = (e) => {
142
+ if (e.dataset.value)
143
+ return e.dataset.value;
144
+ if (e.type === "checkbox")
145
+ return e.checked;
146
+ if (e.type === "number")
147
+ return e.valueAsNumber;
148
+ return e.value || e.getAttribute("value");
149
+ };
150
+ const getDataTarget = (e) => {
151
+ const target = e.dataset.target;
152
+ if (!target)
153
+ return getValueByType(e);
154
+ const element = document.querySelector(`[data-origin="${target}"]`);
155
+ if (!element)
156
+ return getValueByType(e);
157
+ return getValueByType(element);
158
+ };
159
+ const getName = (e) => e.dataset.target || e.name;
160
+ /**
161
+ * Creates a form storage interceptor for persisting form state
162
+ * @param name - The unique name for the form storage
163
+ * @returns An interceptor object with get, set, and clear methods
164
+ */
165
+ export const createFormStorage = (name) => {
166
+ const key = `@use-form/${name}`;
167
+ return {
168
+ get: () => {
169
+ const state = LocalStorage.get(key);
170
+ return isValidJSON(state) ? state : {};
171
+ },
172
+ clear: () => void LocalStorage.delete(key),
173
+ set: (s) => LocalStorage.set(key, s),
174
+ };
175
+ };
176
+ /**
177
+ * A comprehensive form management hook with Zod schema validation.
178
+ *
179
+ * Provides form state management, validation, and component binding for React forms.
180
+ * Supports automatic validation, error handling, and form persistence.
181
+ *
182
+ * @example
183
+ * ```tsx
184
+ * const schema = z.object({
185
+ * name: z.string().min(1, "Name is required"),
186
+ * email: z.string().email("Invalid email"),
187
+ * age: z.number().min(18, "Must be 18 or older")
188
+ * });
189
+ *
190
+ * const MyForm = () => {
191
+ * const form = useForm(schema, "user-form");
192
+ *
193
+ * return (
194
+ * <form {...form.controller()} onSubmit={form.onSubmit((e, { data }) => {
195
+ * console.log("Form data:", data);
196
+ * })}>
197
+ * <Input {...form.input("name")} placeholder="Name" />
198
+ * <Input {...form.input("email")} type="email" placeholder="Email" />
199
+ * <Input {...form.input("age")} type="number" placeholder="Age" />
200
+ * <Button type="submit">Submit</Button>
201
+ * </form>
202
+ * );
203
+ * };
204
+ * ```
205
+ *
206
+ * @template T - The Zod schema type
207
+ * @param schema - Zod schema for form validation
208
+ * @param formName - Unique identifier for the form
209
+ * @param opts - Optional configuration including initial state and interceptors
210
+ * @returns Form management object with input helpers and handlers
211
+ */
212
+ export const useForm = (schema, formName, opts = {}) => {
213
+ const loading = opts.loading ?? false;
214
+ const [errors, setErrors] = useState(null);
215
+ const ref = useRef({});
216
+ const [state, setState] = useState(() => {
217
+ if (Is.function(opts?.state))
218
+ return opts.state();
219
+ return opts?.state ?? getDefaults(schema) ?? {};
220
+ });
221
+ const onInvalidField = useCallback((e) => {
222
+ const target = e.target;
223
+ const related = e.currentTarget;
224
+ const isOptional = target.dataset.optional === "true";
225
+ if (isOptional) {
226
+ return;
227
+ }
228
+ const path = getName(target);
229
+ const value = getDataTarget(target) || (related ? getValueByType(related) : "");
230
+ const partialSchema = getSchemaShape(path, schema);
231
+ target.setAttribute("data-initialized", "true");
232
+ if (partialSchema) {
233
+ const validation = partialSchema.safeParse(value);
234
+ const message = validation.success ? undefined : (validation.error.issues[0]?.message ?? "");
235
+ setErrors((prev) => setPath(prev ?? {}, path, message));
236
+ }
237
+ }, [schema]);
238
+ const onInvalid = useCallback((exec) => (event) => {
239
+ const form = event.currentTarget;
240
+ const validationErrors = Object.values(ref.current).reduce((acc, input) => {
241
+ const field = input.element;
242
+ const validation = input.schema.safeParse(getValueByType(field));
243
+ if (field.dataset.ignore === "ignore")
244
+ return acc;
245
+ if (validation.success)
246
+ return acc;
247
+ const errorMessage = validation.error.issues[0]?.message;
248
+ field.setAttribute("data-initialized", "true");
249
+ const name = field.dataset.name || field.name || "";
250
+ return setPath(acc, name, errorMessage);
251
+ }, {});
252
+ const e = Is.empty(validationErrors) ? null : validationErrors;
253
+ setErrors(e);
254
+ console.error(e);
255
+ exec?.({ form, errors: e || {} });
256
+ }, []);
257
+ const datepicker = (name, props) => {
258
+ const validator = getSchemaShape(name, schema);
259
+ const onChange = (date) => {
260
+ if (!isValid(date))
261
+ return;
262
+ setState((prev) => setPath(prev, name, date.toISOString()));
263
+ setErrors((prev) => setPath(prev, name, undefined));
264
+ const input = ref.current[name].element;
265
+ if (input) {
266
+ const origin = input.getAttribute("data-origin");
267
+ const inputShadow = document.querySelector(`input[data-target="${origin}"]`);
268
+ if (inputShadow)
269
+ inputShadow.setCustomValidity("");
270
+ }
271
+ props?.onChange?.(date);
272
+ };
273
+ return {
274
+ ...props,
275
+ loading,
276
+ name,
277
+ id: name,
278
+ onChange,
279
+ form: formName,
280
+ date: Is.string(state[name]) ? new Date(state[name]) : state[name],
281
+ required: props?.required ?? !validator.isOptional(),
282
+ error: getPath(errors, name),
283
+ ref: (e) => {
284
+ if (e === null)
285
+ return;
286
+ ref.current[name] = { element: e, schema: validator };
287
+ },
288
+ };
289
+ };
290
+ const select = (name, props) => {
291
+ const validator = getSchemaShape(name, schema);
292
+ const onChange = (e) => {
293
+ const value = e.target.value;
294
+ setState((prev) => setPath(prev, name, value));
295
+ // SelectProps/AutocompleteProps have divergent onChange signatures at this generic union boundary
296
+ props?.onChange?.(e);
297
+ };
298
+ return {
299
+ ...props,
300
+ name,
301
+ id: name,
302
+ onChange,
303
+ form: formName,
304
+ loading,
305
+ onInvalid: onInvalidField,
306
+ error: getPath(errors, name, undefined),
307
+ value: getPath(state, name, undefined) ?? "",
308
+ required: props?.required ?? !validator.isOptional(),
309
+ ref: (e) => e !== null
310
+ ? (ref.current[name] = {
311
+ element: e,
312
+ schema: validator,
313
+ })
314
+ : undefined,
315
+ };
316
+ };
317
+ const checkbox = (name, props) => {
318
+ const validator = getSchemaShape(name, schema);
319
+ const onChange = (e) => {
320
+ const value = e.target.checked;
321
+ setState((prev) => setPath(prev ?? {}, name, value));
322
+ props?.onChange?.(e);
323
+ };
324
+ return {
325
+ ...props,
326
+ name,
327
+ id: name,
328
+ onChange,
329
+ form: formName,
330
+ loading,
331
+ onInvalid: onInvalidField,
332
+ error: getPath(errors, name, undefined),
333
+ required: props?.required ?? !validator.isOptional(),
334
+ ref: (e) => e !== null
335
+ ? void (ref.current[name] = {
336
+ element: e,
337
+ schema: validator,
338
+ })
339
+ : undefined,
340
+ };
341
+ };
342
+ const textarea = (name, props) => {
343
+ const validator = getSchemaShape(name, schema);
344
+ const onChange = (e) => {
345
+ e.persist?.();
346
+ const value = e.target.value;
347
+ props?.onChange?.(e);
348
+ setState((prev) => setPath(prev, name, value));
349
+ };
350
+ return {
351
+ ...props,
352
+ loading,
353
+ name,
354
+ id: name,
355
+ onChange,
356
+ form: formName,
357
+ onInvalid: onInvalidField,
358
+ error: getPath(errors, name, undefined),
359
+ required: props?.required ?? !validator.isOptional(),
360
+ value: getPath(state, name, undefined) || props?.value || "",
361
+ type: Is.instance(validator, ZodNumber) ? "number" : (props?.type ?? "text"),
362
+ ref: (e) => e === null
363
+ ? undefined
364
+ : (ref.current[name] = {
365
+ element: e,
366
+ schema: validator,
367
+ }),
368
+ };
369
+ };
370
+ const multiselect = (name, props) => {
371
+ const validator = getSchemaShape(name, schema);
372
+ const onChangeOptions = (options) => {
373
+ setState((prev) => setPath(prev, name, options));
374
+ };
375
+ return {
376
+ ...props,
377
+ name,
378
+ id: name,
379
+ onChangeOptions,
380
+ form: formName,
381
+ loading,
382
+ onInvalid: onInvalidField,
383
+ error: getPath(errors, name, undefined),
384
+ required: props?.required ?? !validator.isOptional(),
385
+ value: getPath(state, name, undefined) || props?.value || [],
386
+ ref: (e) => e === null
387
+ ? undefined
388
+ : void (ref.current[name] = {
389
+ element: e,
390
+ schema: validator,
391
+ }),
392
+ };
393
+ };
394
+ const input = (name, props) => {
395
+ const validator = getSchemaShape(name, schema);
396
+ const isNumber = validator._def.typeName === "ZodNumber";
397
+ const onChange = (e) => {
398
+ e.persist?.();
399
+ const value = isNumber ? e.target.valueAsNumber : e.target.value;
400
+ props?.onChange?.(e);
401
+ setState((prev) => setPath(prev, name, value));
402
+ };
403
+ return {
404
+ ...props,
405
+ name,
406
+ id: name,
407
+ onChange,
408
+ form: formName,
409
+ loading,
410
+ onInvalid: onInvalidField,
411
+ error: getPath(errors, name, undefined),
412
+ required: props?.required ?? !validator.isOptional(),
413
+ type: isNumber ? "number" : (props?.type ?? "text"),
414
+ value: getPath(state, name, undefined) || props?.value || "",
415
+ ref: (e) => e === null
416
+ ? undefined
417
+ : void (ref.current[name] = {
418
+ element: e,
419
+ schema: validator,
420
+ }),
421
+ };
422
+ };
423
+ useEffect(() => {
424
+ const events = Object.values(ref.current).map((input) => {
425
+ const element = input.element.dataset.origin
426
+ ? document.querySelector(`[data-target="${input.element.name}"]`)
427
+ : input.element;
428
+ const validation = input.schema.safeParse(getValueByType(element));
429
+ const onBlurField = (e) => {
430
+ if (e.target === null)
431
+ return false;
432
+ const name = getName(e.target);
433
+ if (!name)
434
+ return false;
435
+ const current = e.target;
436
+ const relatedTarget = e.relatedTarget;
437
+ const value = getDataTarget(current) || (relatedTarget ? getValueByType(relatedTarget) : "");
438
+ const validation = input.schema.safeParse(value);
439
+ current.setAttribute("value", value);
440
+ if (validation.success) {
441
+ if (element.setCustomValidity)
442
+ element.setCustomValidity("");
443
+ setErrors((prev) => {
444
+ if (Is.null(prev))
445
+ return null;
446
+ const newErrors = setPath(prev, name, undefined);
447
+ if (Is.empty(prev) || Is.nil(prev))
448
+ return null;
449
+ return Is.empty(newErrors) ? null : newErrors;
450
+ });
451
+ return false;
452
+ }
453
+ if (element.required) {
454
+ const errorMessage = validation.error.issues[0]?.message || "";
455
+ if (element.setCustomValidity)
456
+ element.setCustomValidity(errorMessage);
457
+ setErrors((prev) => {
458
+ if (Is.null(prev))
459
+ return null;
460
+ const newErrors = setPath(prev, name, errorMessage || undefined);
461
+ return Is.empty(newErrors) ? null : newErrors;
462
+ });
463
+ }
464
+ return false;
465
+ };
466
+ const controller = new AbortController();
467
+ const trigger = element.getAttribute("data-trigger") || "blur";
468
+ element.addEventListener(trigger, onBlurField, { signal: controller.signal });
469
+ const hasInitialError = element.dataset.shadow ? false : element.required ? !validation.success : false;
470
+ return {
471
+ input,
472
+ hasInitialError,
473
+ unsubscribe: () => controller.abort(),
474
+ };
475
+ });
476
+ const hasErrors = events.some((x) => x.hasInitialError);
477
+ if (hasErrors)
478
+ setErrors((prev) => (prev === null ? {} : prev));
479
+ return () => events.forEach((item) => item.unsubscribe());
480
+ }, []);
481
+ const onSubmit = (exec) => (event) => {
482
+ event.preventDefault();
483
+ const form = event.currentTarget;
484
+ let json = formToJson(form);
485
+ const elements = formName ? Array.from(document.querySelectorAll(`[form="${formName}"]`)) : Array.from(form.elements);
486
+ elements.forEach((field) => {
487
+ if (field.tagName === "SELECT") {
488
+ const input = field;
489
+ json = setPath(json, input.name, input.value);
490
+ }
491
+ if (field.tagName === "INPUT") {
492
+ const input = field;
493
+ const value = getDataTarget(input) || (input ? getValueByType(input) : "");
494
+ json = setPath(json, input.dataset.target || input.name, value);
495
+ }
496
+ });
497
+ const input = deepMerge(json, state);
498
+ const result = schema.safeParse(input);
499
+ const reset = () => {
500
+ formReset(form);
501
+ opts.interceptor?.clear();
502
+ };
503
+ if (result.success) {
504
+ const jsonString = JSON.stringify(result.data);
505
+ form.setAttribute("data-json", jsonString);
506
+ opts.interceptor?.clear();
507
+ return exec?.(event, {
508
+ form,
509
+ event,
510
+ reset,
511
+ setErrors,
512
+ errors: [],
513
+ success: true,
514
+ data: result.data,
515
+ json: result.data,
516
+ });
517
+ }
518
+ console.group("useForm error");
519
+ console.info(result);
520
+ console.info(result.error.issues);
521
+ console.error(result.error);
522
+ console.groupEnd();
523
+ form.reportValidity();
524
+ return exec?.(event, {
525
+ form,
526
+ json,
527
+ event,
528
+ reset,
529
+ setErrors,
530
+ data: json,
531
+ success: false,
532
+ errors: result.error.issues.map((x) => ({ message: x.message, path: x.path.map((x) => String(x)) })),
533
+ });
534
+ };
535
+ const get = (p) => getPath(state, p) || "";
536
+ const controller = (props) => ({
537
+ ...props,
538
+ id: formName,
539
+ name: formName,
540
+ });
541
+ useEffect(() => {
542
+ if (opts.interceptor)
543
+ opts.interceptor?.set(state);
544
+ }, [state, opts.interceptor]);
545
+ return {
546
+ get,
547
+ input,
548
+ state,
549
+ errors,
550
+ select,
551
+ checkbox,
552
+ onSubmit,
553
+ setState,
554
+ textarea,
555
+ onInvalid,
556
+ controller,
557
+ datepicker,
558
+ name: formName,
559
+ multiselect,
560
+ disabled: errors !== null,
561
+ };
562
+ };
563
+ export const getJsonForm = (form) => !form ? {} : JSON.parse(form.getAttribute("data-json"));
@@ -0,0 +1,3 @@
1
+ import { RefObject } from "react";
2
+ export declare const useHover: (ref: RefObject<HTMLElement>) => boolean;
3
+ //# sourceMappingURL=use-hover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-hover.d.ts","sourceRoot":"","sources":["../../src/hooks/use-hover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,OAAO,CAAC;AAEvD,eAAO,MAAM,QAAQ,GAAI,KAAK,SAAS,CAAC,WAAW,CAAC,YAiBnD,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { useEffect, useState } from "react";
2
+ export const useHover = (ref) => {
3
+ const [hovered, setHovered] = useState(false);
4
+ const enter = () => setHovered(true);
5
+ const leave = () => setHovered(false);
6
+ useEffect(() => {
7
+ const el = ref.current; // cache external ref value for use in cleanup
8
+ if (el) {
9
+ el.addEventListener("mouseenter", enter);
10
+ el.addEventListener("mouseleave", leave);
11
+ return () => {
12
+ el.removeEventListener("mouseenter", enter);
13
+ el.removeEventListener("mouseleave", leave);
14
+ };
15
+ }
16
+ }, [ref]);
17
+ return hovered;
18
+ };
@@ -0,0 +1,4 @@
1
+ type S = string | undefined;
2
+ export declare const useInputId: (id: S, name: S) => string;
3
+ export {};
4
+ //# sourceMappingURL=use-input-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-input-id.d.ts","sourceRoot":"","sources":["../../src/hooks/use-input-id.ts"],"names":[],"mappings":"AAEA,KAAK,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;AAE5B,eAAO,MAAM,UAAU,GAAI,IAAI,CAAC,EAAE,MAAM,CAAC,WAGxC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { useId } from "react";
2
+ export const useInputId = (id, name) => {
3
+ const same = useId();
4
+ return id || name || same;
5
+ };
@@ -0,0 +1,2 @@
1
+ export declare const useIsCoarseDevice: () => boolean;
2
+ //# sourceMappingURL=use-is-coarse-device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-is-coarse-device.d.ts","sourceRoot":"","sources":["../../src/hooks/use-is-coarse-device.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,QAAO,OASpC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { isSsr } from "../lib/fns";
3
+ const getCoarse = () => window.matchMedia("@media (pointer: coarse)");
4
+ export const useIsCoarseDevice = () => {
5
+ const ref = useRef(isSsr() ? null : getCoarse());
6
+ const [isCoarse, setIsCoarse] = useState(isSsr() ? false : (ref.current?.matches ?? false));
7
+ useEffect(() => {
8
+ const coerse = ref.current === null ? getCoarse() : ref.current;
9
+ coerse.addEventListener("change", (e) => setIsCoarse(e.matches));
10
+ }, []);
11
+ return isCoarse;
12
+ };
@@ -0,0 +1,3 @@
1
+ import type { Locales } from "the-mask-input";
2
+ export declare const useLocale: (locale?: Locales) => Locales | undefined;
3
+ //# sourceMappingURL=use-locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-locale.d.ts","sourceRoot":"","sources":["../../src/hooks/use-locale.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,eAAO,MAAM,SAAS,GAAI,SAAS,OAAO,KAAG,OAAO,GAAG,SAKtD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { useContext } from "react";
2
+ import { Context } from "../config/context";
3
+ export const useLocale = (locale) => {
4
+ const ctx = useContext(Context);
5
+ if (locale)
6
+ return locale;
7
+ if (!ctx)
8
+ return undefined;
9
+ return ctx.locale || locale;
10
+ };
@@ -0,0 +1,2 @@
1
+ export declare const useMediaQuery: (query: string, defaultValue?: boolean) => boolean;
2
+ //# sourceMappingURL=use-media-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-query.d.ts","sourceRoot":"","sources":["../../src/hooks/use-media-query.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,eAAc,OAAc,YAkBxE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+ import { isSsr } from "../lib/fns";
3
+ const getMatches = (query, defaultValue) => {
4
+ if (isSsr()) {
5
+ return defaultValue;
6
+ }
7
+ return window.matchMedia(query).matches;
8
+ };
9
+ export const useMediaQuery = (query, defaultValue = true) => {
10
+ const [matches, setMatches] = useState(defaultValue);
11
+ useLayoutEffect(() => {
12
+ const matchMedia = window.matchMedia(query);
13
+ const onChange = () => setMatches(getMatches(query, defaultValue));
14
+ onChange();
15
+ if (matchMedia.addListener) {
16
+ matchMedia.addListener(onChange);
17
+ return () => {
18
+ return matchMedia.removeListener ? matchMedia.removeListener(onChange) : undefined;
19
+ };
20
+ }
21
+ matchMedia.addEventListener("change", onChange);
22
+ return () => matchMedia.removeEventListener("change", onChange);
23
+ }, [query, defaultValue]);
24
+ return matches;
25
+ };
@@ -0,0 +1,4 @@
1
+ type Listener<K extends keyof WindowEventMap> = (event: WindowEventMap[K]) => void;
2
+ export declare const useOnEvent: <K extends keyof WindowEventMap>(event: K, func: Listener<K>) => void;
3
+ export {};
4
+ //# sourceMappingURL=use-on-event.d.ts.map