@g4rcez/components 3.0.0-0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/dist/ai/SKILL.md +266 -0
  2. package/dist/ai/docs/Alert.md +167 -0
  3. package/dist/ai/docs/AnimatedList.md +205 -0
  4. package/dist/ai/docs/Autocomplete.md +225 -0
  5. package/dist/ai/docs/Button.md +182 -0
  6. package/dist/ai/docs/Calendar.md +219 -0
  7. package/dist/ai/docs/Card.md +174 -0
  8. package/dist/ai/docs/Checkbox.md +199 -0
  9. package/dist/ai/docs/CommandPalette.md +293 -0
  10. package/dist/ai/docs/DatePicker.md +171 -0
  11. package/dist/ai/docs/Dropdown.md +223 -0
  12. package/dist/ai/docs/Empty.md +163 -0
  13. package/dist/ai/docs/Expand.md +143 -0
  14. package/dist/ai/docs/FileUpload.md +225 -0
  15. package/dist/ai/docs/Form.md +107 -0
  16. package/dist/ai/docs/FormReset.md +117 -0
  17. package/dist/ai/docs/Heading.md +88 -0
  18. package/dist/ai/docs/Input.md +237 -0
  19. package/dist/ai/docs/InputField.md +170 -0
  20. package/dist/ai/docs/List.md +205 -0
  21. package/dist/ai/docs/Menu.md +166 -0
  22. package/dist/ai/docs/Modal.md +280 -0
  23. package/dist/ai/docs/MultiSelect.md +196 -0
  24. package/dist/ai/docs/Notifications.md +231 -0
  25. package/dist/ai/docs/PageCalendar.md +271 -0
  26. package/dist/ai/docs/Polymorph.md +159 -0
  27. package/dist/ai/docs/Progress.md +145 -0
  28. package/dist/ai/docs/Radiobox.md +128 -0
  29. package/dist/ai/docs/RenderOnView.md +138 -0
  30. package/dist/ai/docs/Resizable.md +159 -0
  31. package/dist/ai/docs/Select.md +284 -0
  32. package/dist/ai/docs/Shortcut.md +105 -0
  33. package/dist/ai/docs/Skeleton.md +166 -0
  34. package/dist/ai/docs/Slider.md +144 -0
  35. package/dist/ai/docs/Slot.md +173 -0
  36. package/dist/ai/docs/Spinner.md +118 -0
  37. package/dist/ai/docs/Stats.md +137 -0
  38. package/dist/ai/docs/Step.md +159 -0
  39. package/dist/ai/docs/Switch.md +167 -0
  40. package/dist/ai/docs/Table.md +298 -0
  41. package/dist/ai/docs/Tabs.md +191 -0
  42. package/dist/ai/docs/Tag.md +224 -0
  43. package/dist/ai/docs/TaskList.md +144 -0
  44. package/dist/ai/docs/Textarea.md +167 -0
  45. package/dist/ai/docs/Timeline.md +210 -0
  46. package/dist/ai/docs/Toolbar.md +132 -0
  47. package/dist/ai/docs/Tooltip.md +231 -0
  48. package/dist/ai/docs/TransferList.md +142 -0
  49. package/dist/ai/docs/Typography.md +187 -0
  50. package/dist/ai/docs/Wizard.md +213 -0
  51. package/dist/ai/docs/index.md +183 -0
  52. package/dist/components/core/button.d.ts +2 -8
  53. package/dist/components/core/button.d.ts.map +1 -1
  54. package/dist/components/core/polymorph.d.ts.map +1 -1
  55. package/dist/components/core/slot.d.ts +1 -1
  56. package/dist/components/core/slot.d.ts.map +1 -1
  57. package/dist/components/core/tag.d.ts +2 -2
  58. package/dist/components/core/tag.d.ts.map +1 -1
  59. package/dist/components/core/typography.d.ts.map +1 -1
  60. package/dist/components/display/alert.d.ts.map +1 -1
  61. package/dist/components/display/calendar.d.ts.map +1 -1
  62. package/dist/components/display/card.d.ts.map +1 -1
  63. package/dist/components/display/list.d.ts.map +1 -1
  64. package/dist/components/display/notifications.d.ts +2 -0
  65. package/dist/components/display/notifications.d.ts.map +1 -1
  66. package/dist/components/display/progress.d.ts.map +1 -1
  67. package/dist/components/display/skeleton.d.ts.map +1 -1
  68. package/dist/components/display/step.d.ts.map +1 -1
  69. package/dist/components/display/tabs.d.ts.map +1 -1
  70. package/dist/components/floating/command-palette.d.ts +1 -0
  71. package/dist/components/floating/command-palette.d.ts.map +1 -1
  72. package/dist/components/floating/dropdown.d.ts +1 -0
  73. package/dist/components/floating/dropdown.d.ts.map +1 -1
  74. package/dist/components/floating/menu.d.ts +2 -2
  75. package/dist/components/floating/menu.d.ts.map +1 -1
  76. package/dist/components/floating/modal.d.ts +20 -53
  77. package/dist/components/floating/modal.d.ts.map +1 -1
  78. package/dist/components/floating/tooltip.d.ts.map +1 -1
  79. package/dist/components/floating/wizard.d.ts +1 -1
  80. package/dist/components/floating/wizard.d.ts.map +1 -1
  81. package/dist/components/form/autocomplete.d.ts.map +1 -1
  82. package/dist/components/form/date-picker.d.ts.map +1 -1
  83. package/dist/components/form/free-text.d.ts.map +1 -1
  84. package/dist/components/form/input-field.d.ts +3 -2
  85. package/dist/components/form/input-field.d.ts.map +1 -1
  86. package/dist/components/form/multi-select.d.ts.map +1 -1
  87. package/dist/components/form/select.d.ts.map +1 -1
  88. package/dist/components/form/slider.d.ts.map +1 -1
  89. package/dist/components/index.d.ts +2 -0
  90. package/dist/components/index.d.ts.map +1 -1
  91. package/dist/components/page-calendar/calendar-header.d.ts +16 -0
  92. package/dist/components/page-calendar/calendar-header.d.ts.map +1 -0
  93. package/dist/components/page-calendar/day-view.d.ts +12 -0
  94. package/dist/components/page-calendar/day-view.d.ts.map +1 -0
  95. package/dist/components/page-calendar/event-pill.d.ts +9 -0
  96. package/dist/components/page-calendar/event-pill.d.ts.map +1 -0
  97. package/dist/components/page-calendar/index.d.ts +4 -0
  98. package/dist/components/page-calendar/index.d.ts.map +1 -0
  99. package/dist/components/page-calendar/month-view.d.ts +11 -0
  100. package/dist/components/page-calendar/month-view.d.ts.map +1 -0
  101. package/dist/components/page-calendar/page-calendar.d.ts +18 -0
  102. package/dist/components/page-calendar/page-calendar.d.ts.map +1 -0
  103. package/dist/components/page-calendar/page-calendar.types.d.ts +18 -0
  104. package/dist/components/page-calendar/page-calendar.types.d.ts.map +1 -0
  105. package/dist/components/page-calendar/page-calendar.utils.d.ts +18 -0
  106. package/dist/components/page-calendar/page-calendar.utils.d.ts.map +1 -0
  107. package/dist/components/page-calendar/week-view.d.ts +11 -0
  108. package/dist/components/page-calendar/week-view.d.ts.map +1 -0
  109. package/dist/components/table/index.d.ts.map +1 -1
  110. package/dist/components/table/inner-table.d.ts.map +1 -1
  111. package/dist/components/table/metadata.d.ts.map +1 -1
  112. package/dist/components/table/row.d.ts.map +1 -1
  113. package/dist/components/table/table-lib.d.ts.map +1 -1
  114. package/dist/components/table/thead.d.ts.map +1 -1
  115. package/dist/config/context.d.ts.map +1 -1
  116. package/dist/config/default-translations.d.ts +21 -4
  117. package/dist/config/default-translations.d.ts.map +1 -1
  118. package/dist/constants.d.ts.map +1 -1
  119. package/dist/hooks/use-components-provider.d.ts.map +1 -1
  120. package/dist/hooks/use-form.d.ts +11 -11
  121. package/dist/hooks/use-form.d.ts.map +1 -1
  122. package/dist/hooks/use-input-id.d.ts.map +1 -1
  123. package/dist/hooks/use-preferences.d.ts.map +1 -1
  124. package/dist/hooks/use-previous.d.ts.map +1 -1
  125. package/dist/hooks/use-reactive.d.ts.map +1 -1
  126. package/dist/hooks/use-resize-observer.d.ts.map +1 -1
  127. package/dist/hooks/use-stable-ref.d.ts.map +1 -1
  128. package/dist/hooks/use-swipe.d.ts.map +1 -1
  129. package/dist/hooks/use-translations.d.ts +21 -4
  130. package/dist/hooks/use-translations.d.ts.map +1 -1
  131. package/dist/index.css +1 -0
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +28 -20
  134. package/dist/index.js.map +1 -1
  135. package/dist/index.mjs +13862 -12512
  136. package/dist/index.mjs.map +1 -1
  137. package/dist/index.umd.js +24 -17
  138. package/dist/index.umd.js.map +1 -1
  139. package/dist/lib/dom.d.ts +1 -0
  140. package/dist/lib/dom.d.ts.map +1 -1
  141. package/dist/lib/fns.d.ts.map +1 -1
  142. package/dist/preset/plugin.tailwind.d.ts +9 -0
  143. package/dist/preset/plugin.tailwind.d.ts.map +1 -0
  144. package/dist/preset/plugin.tailwind.js +27 -0
  145. package/dist/preset/preset.tailwind.d.ts +8 -0
  146. package/dist/preset/preset.tailwind.d.ts.map +1 -0
  147. package/dist/preset/preset.tailwind.js +54 -0
  148. package/dist/preset/src/styles/common.d.ts +2 -14
  149. package/dist/preset/src/styles/common.d.ts.map +1 -1
  150. package/dist/preset/src/styles/common.js +1 -0
  151. package/dist/preset/src/styles/dark.d.ts.map +1 -1
  152. package/dist/preset/src/styles/dark.js +119 -114
  153. package/dist/preset/src/styles/light.d.ts.map +1 -1
  154. package/dist/preset/src/styles/light.js +111 -106
  155. package/dist/preset/src/styles/theme.types.d.ts +17 -8
  156. package/dist/preset/src/styles/theme.types.d.ts.map +1 -1
  157. package/dist/styles/common.d.ts +2 -14
  158. package/dist/styles/common.d.ts.map +1 -1
  159. package/dist/styles/dark.d.ts.map +1 -1
  160. package/dist/styles/light.d.ts.map +1 -1
  161. package/dist/styles/theme.types.d.ts +17 -8
  162. package/dist/styles/theme.types.d.ts.map +1 -1
  163. package/package.json +299 -301
  164. package/dist/components/core/button.jsx +0 -86
  165. package/dist/components/core/heading.jsx +0 -4
  166. package/dist/components/core/polymorph.jsx +0 -5
  167. package/dist/components/core/render-on-view.jsx +0 -31
  168. package/dist/components/core/resizable.jsx +0 -51
  169. package/dist/components/core/slot.jsx +0 -163
  170. package/dist/components/core/tag.jsx +0 -51
  171. package/dist/components/core/typography.jsx +0 -26
  172. package/dist/components/display/alert.jsx +0 -56
  173. package/dist/components/display/calendar.jsx +0 -301
  174. package/dist/components/display/card.jsx +0 -43
  175. package/dist/components/display/empty.jsx +0 -11
  176. package/dist/components/display/list.jsx +0 -81
  177. package/dist/components/display/notifications.jsx +0 -98
  178. package/dist/components/display/progress.jsx +0 -13
  179. package/dist/components/display/shortcut.jsx +0 -23
  180. package/dist/components/display/skeleton.jsx +0 -14
  181. package/dist/components/display/spinner.jsx +0 -7
  182. package/dist/components/display/stats.jsx +0 -20
  183. package/dist/components/display/step.jsx +0 -131
  184. package/dist/components/display/tabs.jsx +0 -100
  185. package/dist/components/display/timeline.jsx +0 -25
  186. package/dist/components/floating/command-palette.jsx +0 -172
  187. package/dist/components/floating/dropdown.jsx +0 -53
  188. package/dist/components/floating/expand.jsx +0 -44
  189. package/dist/components/floating/menu.jsx +0 -147
  190. package/dist/components/floating/modal.jsx +0 -241
  191. package/dist/components/floating/toolbar.jsx +0 -5
  192. package/dist/components/floating/tooltip.jsx +0 -64
  193. package/dist/components/floating/wizard.jsx +0 -164
  194. package/dist/components/form/autocomplete.jsx +0 -275
  195. package/dist/components/form/checkbox.jsx +0 -12
  196. package/dist/components/form/date-picker.jsx +0 -115
  197. package/dist/components/form/file-upload.jsx +0 -133
  198. package/dist/components/form/form.jsx +0 -10
  199. package/dist/components/form/formReset.jsx +0 -17
  200. package/dist/components/form/free-text.jsx +0 -41
  201. package/dist/components/form/input-field.jsx +0 -54
  202. package/dist/components/form/input.jsx +0 -36
  203. package/dist/components/form/multi-select.jsx +0 -328
  204. package/dist/components/form/radiobox.jsx +0 -6
  205. package/dist/components/form/select.jsx +0 -42
  206. package/dist/components/form/slider.jsx +0 -45
  207. package/dist/components/form/switch.jsx +0 -46
  208. package/dist/components/form/task-list.jsx +0 -26
  209. package/dist/components/form/textarea.jsx +0 -12
  210. package/dist/components/form/transfer-list.jsx +0 -39
  211. package/dist/components/index.js +0 -43
  212. package/dist/components/table/filter.jsx +0 -141
  213. package/dist/components/table/group.jsx +0 -68
  214. package/dist/components/table/index.jsx +0 -60
  215. package/dist/components/table/inner-table.jsx +0 -104
  216. package/dist/components/table/metadata.jsx +0 -37
  217. package/dist/components/table/pagination.jsx +0 -73
  218. package/dist/components/table/row.jsx +0 -58
  219. package/dist/components/table/sort.jsx +0 -105
  220. package/dist/components/table/table-lib.js +0 -84
  221. package/dist/components/table/table.context.jsx +0 -4
  222. package/dist/components/table/thead.jsx +0 -103
  223. package/dist/config/context.js +0 -12
  224. package/dist/config/default-translations.jsx +0 -66
  225. package/dist/config/default-tweaks.js +0 -4
  226. package/dist/constants.js +0 -2
  227. package/dist/hooks/use-click-outside.js +0 -17
  228. package/dist/hooks/use-color-parser.js +0 -9
  229. package/dist/hooks/use-components-provider.jsx +0 -16
  230. package/dist/hooks/use-debounce.js +0 -12
  231. package/dist/hooks/use-floating-ref.js +0 -6
  232. package/dist/hooks/use-form.js +0 -549
  233. package/dist/hooks/use-hover.js +0 -18
  234. package/dist/hooks/use-input-id.js +0 -5
  235. package/dist/hooks/use-is-coarse-device.js +0 -12
  236. package/dist/hooks/use-locale.js +0 -10
  237. package/dist/hooks/use-media-query.js +0 -25
  238. package/dist/hooks/use-on-event.js +0 -7
  239. package/dist/hooks/use-parent.js +0 -21
  240. package/dist/hooks/use-preferences.js +0 -23
  241. package/dist/hooks/use-previous.js +0 -8
  242. package/dist/hooks/use-reactive.js +0 -8
  243. package/dist/hooks/use-remove-scroll.js +0 -61
  244. package/dist/hooks/use-resize-observer.js +0 -17
  245. package/dist/hooks/use-stable-ref.js +0 -8
  246. package/dist/hooks/use-swipe.js +0 -16
  247. package/dist/hooks/use-translations.js +0 -9
  248. package/dist/hooks/use-tweaks.js +0 -9
  249. package/dist/hooks/use-window-size.js +0 -14
  250. package/dist/lib/combi-keys.js +0 -60
  251. package/dist/lib/dict.js +0 -39
  252. package/dist/lib/dom.js +0 -44
  253. package/dist/lib/fns.js +0 -46
  254. package/dist/lib/fzf.js +0 -117
  255. package/dist/lib/keyboard-area.js +0 -14
  256. package/dist/preset/tailwindcssv4.d.ts +0 -3
  257. package/dist/preset/tailwindcssv4.d.ts.map +0 -1
  258. package/dist/preset/tailwindcssv4.js +0 -75
  259. package/dist/styles/common.js +0 -28
  260. package/dist/styles/dark.js +0 -209
  261. package/dist/styles/design-tokens.js +0 -69
  262. package/dist/styles/light.js +0 -209
  263. package/dist/styles/theme.js +0 -4
  264. package/dist/styles/theme.types.js +0 -1
  265. package/dist/types.js +0 -1
@@ -1,549 +0,0 @@
1
- import { isValid } from "date-fns";
2
- import { parse } from "qs";
3
- import { useCallback, useEffect, useRef, useState } from "react";
4
- import { getPath, Is } from "sidekicker";
5
- import { LocalStorage } from "storage-manager-js";
6
- import { ZodNumber } from "zod";
7
- import { formReset, } from "../components";
8
- import { path } from "../lib/fns";
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
- if (typeof value !== "string") {
17
- try {
18
- value = JSON.stringify(value);
19
- }
20
- catch {
21
- return false;
22
- }
23
- }
24
- try {
25
- JSON.parse(value);
26
- return true;
27
- }
28
- catch {
29
- return false;
30
- }
31
- };
32
- const setHelper = (obj, path, value) => {
33
- const lastIndex = path.length - 1;
34
- for (let i = 0; i < path.length; i++) {
35
- const key = path[i];
36
- if (i === lastIndex) {
37
- obj[key] = value;
38
- }
39
- else {
40
- if (!(key in obj) || typeof obj[key] !== "object") {
41
- const nextKey = path[i + 1];
42
- obj[key] = isNaN(Number(nextKey)) ? {} : [];
43
- }
44
- obj = obj[key];
45
- }
46
- }
47
- };
48
- const convertPath = (path) => path.replace(/\[(\d+)]/g, ".$1").split(".");
49
- const setPath = (o, path, value) => {
50
- const pathArr = Array.isArray(path) ? path.map(String) : convertPath(path);
51
- const obj = structuredClone(o);
52
- setHelper(obj, pathArr, value);
53
- return obj;
54
- };
55
- const sort = (a, b) => a.localeCompare(b);
56
- const noop = {};
57
- const getDefaultValue = (inner) => {
58
- const instanceName = inner._def.typeName;
59
- if (instanceName === "ZodDefault")
60
- return inner._def.defaultValue();
61
- if (instanceName === "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
- const result = structuredClone(a);
78
- for (const key in b) {
79
- const bValue = b[key];
80
- const aValue = a[key];
81
- if (bValue !== undefined) {
82
- if (typeof bValue === "object" &&
83
- bValue !== null &&
84
- !Array.isArray(bValue) &&
85
- typeof aValue === "object" &&
86
- aValue !== null &&
87
- !Array.isArray(aValue)) {
88
- result[key] = deepMerge(aValue, bValue);
89
- }
90
- else {
91
- result[key] = bValue ? bValue : aValue;
92
- }
93
- }
94
- }
95
- return result;
96
- };
97
- const options = {
98
- sort,
99
- allowDots: true,
100
- charset: "utf-8",
101
- parseArrays: true,
102
- plainObjects: true,
103
- charsetSentinel: true,
104
- allowPrototypes: false,
105
- depth: Number.MAX_SAFE_INTEGER,
106
- arrayLimit: Number.MAX_SAFE_INTEGER,
107
- parameterLimit: Number.MAX_SAFE_INTEGER,
108
- };
109
- /**
110
- * Converts a form element to a JSON object
111
- * @param form - The HTML form element to convert
112
- * @returns A JSON object representing the form data
113
- */
114
- export const formToJson = (form) => {
115
- const formData = new FormData(form);
116
- const urlSearchParams = new URLSearchParams(formData);
117
- return parse(urlSearchParams.toString(), options);
118
- };
119
- export const getSchemaShape = (name, schema) => {
120
- return convertPath(name).reduce((acc, el) => {
121
- if (el === "")
122
- return acc;
123
- const shape = acc.shape?.[el] || acc;
124
- return shape._def.typeName === "ZodArray" ? shape.element : shape;
125
- }, schema);
126
- };
127
- const getValueByType = (e) => {
128
- if (e.dataset.value)
129
- return e.dataset.value;
130
- if (e.type === "checkbox")
131
- return e.checked;
132
- if (e.type === "number")
133
- return e.valueAsNumber;
134
- return e.value || e.getAttribute("value");
135
- };
136
- const getDataTarget = (e) => {
137
- const target = e.dataset.target;
138
- if (!target)
139
- return getValueByType(e);
140
- const element = document.querySelector(`[data-origin="${target}"]`);
141
- if (!element)
142
- return getValueByType(e);
143
- return getValueByType(element);
144
- };
145
- const defaultOptions = {
146
- state: {},
147
- loading: false,
148
- useOnChange: false,
149
- };
150
- const getName = (e) => e.dataset.target || e.name;
151
- /**
152
- * Creates a form storage interceptor for persisting form state
153
- * @param name - The unique name for the form storage
154
- * @returns An interceptor object with get, set, and clear methods
155
- */
156
- export const createFormStorage = (name) => {
157
- const key = `@use-form/${name}`;
158
- return {
159
- get: () => {
160
- const state = LocalStorage.get(key);
161
- return isValidJSON(state) ? state : {};
162
- },
163
- clear: () => void LocalStorage.delete(key),
164
- set: (s) => LocalStorage.set(key, s),
165
- };
166
- };
167
- /**
168
- * A comprehensive form management hook with Zod schema validation.
169
- *
170
- * Provides form state management, validation, and component binding for React forms.
171
- * Supports automatic validation, error handling, and form persistence.
172
- *
173
- * @example
174
- * ```tsx
175
- * const schema = z.object({
176
- * name: z.string().min(1, "Name is required"),
177
- * email: z.string().email("Invalid email"),
178
- * age: z.number().min(18, "Must be 18 or older")
179
- * });
180
- *
181
- * const MyForm = () => {
182
- * const form = useForm(schema, "user-form");
183
- *
184
- * return (
185
- * <form {...form.controller()} onSubmit={form.onSubmit((e, { data }) => {
186
- * console.log("Form data:", data);
187
- * })}>
188
- * <Input {...form.input("name")} placeholder="Name" />
189
- * <Input {...form.input("email")} type="email" placeholder="Email" />
190
- * <Input {...form.input("age")} type="number" placeholder="Age" />
191
- * <Button type="submit">Submit</Button>
192
- * </form>
193
- * );
194
- * };
195
- * ```
196
- *
197
- * @template T - The Zod schema type
198
- * @param schema - Zod schema for form validation
199
- * @param formName - Unique identifier for the form
200
- * @param opts - Optional configuration including initial state and interceptors
201
- * @returns Form management object with input helpers and handlers
202
- */
203
- export const useForm = (schema, formName, opts = defaultOptions) => {
204
- const [errors, setErrors] = useState(null);
205
- const ref = useRef({});
206
- const [state, setState] = useState(() => {
207
- if (Is.function(opts?.state))
208
- return opts.state();
209
- return opts?.state ?? getDefaults(schema) ?? {};
210
- });
211
- const onInvalidField = useCallback((e) => {
212
- const target = e.target;
213
- const related = e.currentTarget;
214
- const isOptional = target.dataset.optional === "true";
215
- if (isOptional) {
216
- return;
217
- }
218
- const path = getName(target);
219
- const value = getDataTarget(target) || (related ? getValueByType(related) : "");
220
- const partialSchema = getSchemaShape(path, schema);
221
- target.setAttribute("data-initialized", "true");
222
- if (partialSchema) {
223
- const validation = partialSchema.safeParse(value);
224
- const message = validation.success ? undefined : (validation.error.issues[0]?.message ?? "");
225
- setErrors((prev) => setPath(prev ?? {}, path, message));
226
- }
227
- }, [schema]);
228
- const onInvalid = useCallback((exec) => (event) => {
229
- const form = event.currentTarget;
230
- const validationErrors = Object.values(ref.current).reduce((acc, input) => {
231
- const field = input.element;
232
- const validation = input.schema.safeParse(getValueByType(field));
233
- if (field.dataset.ignore === "ignore")
234
- return acc;
235
- if (validation.success)
236
- return acc;
237
- const errorMessage = validation.error.issues[0]?.message;
238
- field.setAttribute("data-initialized", "true");
239
- const name = field.dataset.name || field.name || "";
240
- return setPath(acc, name, errorMessage);
241
- }, {});
242
- const e = Is.empty(validationErrors) ? null : validationErrors;
243
- setErrors(e);
244
- console.error(e);
245
- exec?.({ form, errors: e || {} });
246
- }, []);
247
- const datepicker = (name, props = noop) => {
248
- const validator = getSchemaShape(name, schema);
249
- const onChange = (date) => {
250
- if (!isValid(date))
251
- return;
252
- setState((prev) => setPath(prev, name, date.toISOString()));
253
- setErrors((prev) => setPath(prev, name, undefined));
254
- const input = ref.current[name].element;
255
- if (input) {
256
- const origin = input.getAttribute("data-origin");
257
- const inputShadow = document.querySelector(`input[data-target="${origin}"]`);
258
- if (inputShadow)
259
- inputShadow.setCustomValidity("");
260
- }
261
- props?.onChange?.(date);
262
- };
263
- return {
264
- ...props,
265
- loading: opts.loading,
266
- name,
267
- id: name,
268
- onChange,
269
- form: formName,
270
- date: Is.string(state[name]) ? new Date(state[name]) : state[name],
271
- required: props.required ?? !validator.isOptional(),
272
- error: getPath(errors, name),
273
- ref: (e) => {
274
- if (e === null)
275
- return;
276
- ref.current[name] = { element: e, schema: validator };
277
- },
278
- };
279
- };
280
- const select = (name, props = noop) => {
281
- const validator = getSchemaShape(name, schema);
282
- const onChange = (e) => {
283
- const value = e.target.value;
284
- setState((prev) => setPath(prev, name, value));
285
- props?.onChange?.(e);
286
- };
287
- return {
288
- ...props,
289
- name,
290
- id: name,
291
- onChange,
292
- form: formName,
293
- loading: opts.loading,
294
- onInvalid: onInvalidField,
295
- error: getPath(errors, name, undefined),
296
- value: getPath(state, name, undefined) ?? "",
297
- required: props.required ?? !validator.isOptional(),
298
- ref: (e) => e !== null
299
- ? (ref.current[name] = {
300
- element: e,
301
- schema: validator,
302
- })
303
- : undefined,
304
- };
305
- };
306
- const checkbox = (name, props = noop) => {
307
- const validator = getSchemaShape(name, schema);
308
- const onChange = (e) => {
309
- const value = e.target.checked;
310
- setState((prev) => setPath(prev ?? {}, name, value));
311
- props?.onChange?.(e);
312
- };
313
- return {
314
- ...props,
315
- name,
316
- id: name,
317
- onChange,
318
- form: formName,
319
- loading: opts.loading,
320
- onInvalid: onInvalidField,
321
- error: getPath(errors, name, undefined),
322
- required: props.required ?? !validator.isOptional(),
323
- ref: (e) => e !== null
324
- ? void (ref.current[name] = {
325
- element: e,
326
- schema: validator,
327
- })
328
- : undefined,
329
- };
330
- };
331
- const textarea = (name, props = noop) => {
332
- const validator = getSchemaShape(name, schema);
333
- const onChange = (e) => {
334
- e.persist?.();
335
- const value = e.target.value;
336
- props?.onChange?.(e);
337
- setState((prev) => setPath(prev, name, value));
338
- };
339
- return {
340
- ...props,
341
- loading: opts.loading,
342
- name,
343
- id: name,
344
- onChange,
345
- form: formName,
346
- onInvalid: onInvalidField,
347
- error: getPath(errors, name, undefined),
348
- required: props.required ?? !validator.isOptional(),
349
- value: getPath(state, name, undefined) || props?.value || "",
350
- type: Is.instance(validator, ZodNumber) ? "number" : (props?.type ?? "text"),
351
- ref: (e) => e === null
352
- ? undefined
353
- : (ref.current[name] = {
354
- element: e,
355
- schema: validator,
356
- }),
357
- };
358
- };
359
- const multiselect = (name, props = noop) => {
360
- const validator = getSchemaShape(name, schema);
361
- const onChangeOptions = (options) => {
362
- setState((prev) => setPath(prev, name, options));
363
- };
364
- return {
365
- ...props,
366
- name,
367
- id: name,
368
- onChangeOptions,
369
- form: formName,
370
- loading: opts.loading,
371
- onInvalid: onInvalidField,
372
- error: getPath(errors, name, undefined),
373
- required: props.required ?? !validator.isOptional(),
374
- value: getPath(state, name, undefined) || props?.value || [],
375
- ref: (e) => e === null
376
- ? undefined
377
- : void (ref.current[name] = {
378
- element: e,
379
- schema: validator,
380
- }),
381
- };
382
- };
383
- const input = (name, props = noop) => {
384
- const validator = getSchemaShape(name, schema);
385
- const isNumber = validator._def.typeName === "ZodNumber";
386
- const onChange = (e) => {
387
- e.persist?.();
388
- const value = isNumber ? e.target.valueAsNumber : e.target.value;
389
- props?.onChange?.(e);
390
- setState((prev) => setPath(prev, name, value));
391
- };
392
- return {
393
- ...props,
394
- name,
395
- id: name,
396
- onChange,
397
- form: formName,
398
- loading: opts.loading,
399
- onInvalid: onInvalidField,
400
- error: getPath(errors, name, undefined),
401
- required: props.required ?? !validator.isOptional(),
402
- type: isNumber ? "number" : (props?.type ?? "text"),
403
- value: getPath(state, name, undefined) || props?.value || "",
404
- ref: (e) => e === null
405
- ? undefined
406
- : void (ref.current[name] = {
407
- element: e,
408
- schema: validator,
409
- }),
410
- };
411
- };
412
- useEffect(() => {
413
- const events = Object.values(ref.current).map((input) => {
414
- const element = input.element.dataset.origin
415
- ? document.querySelector(`[data-target="${input.element.name}"]`)
416
- : input.element;
417
- const validation = input.schema.safeParse(getValueByType(element));
418
- const onBlurField = (e) => {
419
- const name = getName(e.target);
420
- if (!name)
421
- return false;
422
- const current = e.target;
423
- const value = getDataTarget(e.target) || (e.relatedTarget ? getValueByType(e.relatedTarget) : "");
424
- const validation = input.schema.safeParse(value);
425
- current.setAttribute("value", value);
426
- if (validation.success) {
427
- if (element.setCustomValidity)
428
- element.setCustomValidity("");
429
- setErrors((prev) => {
430
- if (Is.null(prev))
431
- return null;
432
- const newErrors = setPath(prev, name, undefined);
433
- if (Is.empty(prev) || Is.nil(prev))
434
- return null;
435
- return Is.empty(newErrors) ? null : newErrors;
436
- });
437
- return false;
438
- }
439
- if (element.required) {
440
- const errorMessage = validation.error.issues[0]?.message || "";
441
- if (element.setCustomValidity)
442
- element.setCustomValidity(errorMessage);
443
- setErrors((prev) => {
444
- if (Is.null(prev))
445
- return null;
446
- const newErrors = setPath(prev, name, errorMessage || undefined);
447
- return Is.empty(newErrors) ? null : newErrors;
448
- });
449
- }
450
- return false;
451
- };
452
- const controller = new AbortController();
453
- const trigger = element.getAttribute("data-trigger") || "blur";
454
- element.addEventListener(trigger, onBlurField, { signal: controller.signal });
455
- const hasInitialError = element.dataset.shadow ? false : element.required ? !validation.success : false;
456
- return {
457
- input,
458
- hasInitialError,
459
- unsubscribe: () => controller.abort(),
460
- };
461
- });
462
- const hasErrors = events.some((x) => x.hasInitialError);
463
- if (hasErrors)
464
- setErrors((prev) => (prev === null ? {} : prev));
465
- return () => events.forEach((item) => item.unsubscribe());
466
- });
467
- const onSubmit = (exec) => (event) => {
468
- event.preventDefault();
469
- const form = event.currentTarget;
470
- let json = formToJson(form);
471
- const elements = formName ? Array.from(document.querySelectorAll(`[form="${formName}"]`)) : Array.from(form.elements);
472
- elements.forEach((field) => {
473
- if (field.tagName === "SELECT") {
474
- const input = field;
475
- json = setPath(json, input.name, input.value);
476
- }
477
- if (field.tagName === "INPUT") {
478
- const input = field;
479
- const value = getDataTarget(input) || (input ? getValueByType(input) : "");
480
- json = setPath(json, input.dataset.target || input.name, value);
481
- }
482
- });
483
- const input = deepMerge(json, state);
484
- const result = schema.safeParse(input);
485
- const reset = () => {
486
- formReset(form);
487
- opts.interceptor?.clear();
488
- };
489
- if (result.success) {
490
- const jsonString = JSON.stringify(result.data);
491
- form.setAttribute("data-json", jsonString);
492
- opts.interceptor?.clear();
493
- return exec?.(event, {
494
- form,
495
- event,
496
- reset,
497
- setErrors,
498
- errors: [],
499
- success: true,
500
- data: result.data,
501
- json: result.data,
502
- });
503
- }
504
- console.group("useForm error");
505
- console.info(result);
506
- console.info(result.error.issues);
507
- console.error(result.error);
508
- console.groupEnd();
509
- form.reportValidity();
510
- return exec?.(event, {
511
- form,
512
- json,
513
- event,
514
- reset,
515
- setErrors,
516
- data: json,
517
- success: false,
518
- errors: result.error.issues.map((x) => ({ message: x.message, path: x.path.map((x) => String(x)) })),
519
- });
520
- };
521
- const get = (p) => path(state, p) || "";
522
- const controller = (props) => ({
523
- ...props,
524
- id: formName,
525
- name: formName,
526
- });
527
- useEffect(() => {
528
- if (opts.interceptor)
529
- opts.interceptor?.set(state);
530
- }, [state]);
531
- return {
532
- get,
533
- input,
534
- state,
535
- errors,
536
- select,
537
- checkbox,
538
- onSubmit,
539
- setState,
540
- textarea,
541
- onInvalid,
542
- controller,
543
- datepicker,
544
- name: formName,
545
- multiselect,
546
- disabled: errors !== null,
547
- };
548
- };
549
- export const getJsonForm = (form) => !form ? {} : JSON.parse(form.getAttribute("data-json"));
@@ -1,18 +0,0 @@
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
- }, []);
17
- return hovered;
18
- };
@@ -1,5 +0,0 @@
1
- import { useId } from "react";
2
- export const useInputId = (id, name) => {
3
- const same = useId();
4
- return id || name || same;
5
- };
@@ -1,12 +0,0 @@
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
- };
@@ -1,10 +0,0 @@
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
- };
@@ -1,25 +0,0 @@
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]);
24
- return matches;
25
- };
@@ -1,7 +0,0 @@
1
- import { useEffect } from "react";
2
- export const useOnEvent = (event, func) => {
3
- useEffect(() => {
4
- window.addEventListener(event, func);
5
- return () => window.removeEventListener(event, func);
6
- }, [event]);
7
- };
@@ -1,21 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- export const useParentHeight = (ref) => {
3
- const [h, setH] = useState(0);
4
- useEffect(() => {
5
- const element = ref.current;
6
- if (!element)
7
- return;
8
- const parent = element.parentElement;
9
- if (!parent)
10
- return;
11
- const listener = () => {
12
- setH(parent.clientHeight);
13
- };
14
- parent.addEventListener("resize", listener);
15
- listener();
16
- return () => {
17
- parent.removeEventListener("resize", listener);
18
- };
19
- }, []);
20
- return h;
21
- };
@@ -1,23 +0,0 @@
1
- import { useCallback, useState } from "react";
2
- import { Is } from "sidekicker";
3
- import { LocalStorage } from "storage-manager-js";
4
- export const usePreferences = (key, defaultValue) => {
5
- const [state, setState] = useState(() => {
6
- const saved = LocalStorage.get(key);
7
- if (saved)
8
- return saved;
9
- return defaultValue;
10
- });
11
- const setCallback = useCallback((params) => {
12
- if (Is.function(params)) {
13
- return setState((prev) => {
14
- const result = params(prev);
15
- LocalStorage.set(key, result);
16
- return result;
17
- });
18
- }
19
- LocalStorage.set(key, params);
20
- return params;
21
- }, [key]);
22
- return [state, setCallback];
23
- };
@@ -1,8 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
- export const usePrevious = (value) => {
3
- const ref = useRef(undefined);
4
- useEffect(() => {
5
- ref.current = value;
6
- }, [value]);
7
- return ref.current;
8
- };