@axenstudio/axen-form 0.1.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 (210) hide show
  1. package/README.md +665 -0
  2. package/dist/adapters/yupAdapter.cjs +61 -0
  3. package/dist/adapters/yupAdapter.d.ts +21 -0
  4. package/dist/adapters/yupAdapter.d.ts.map +1 -0
  5. package/dist/adapters/yupAdapter.js +61 -0
  6. package/dist/adapters/zodAdapter.cjs +59 -0
  7. package/dist/adapters/zodAdapter.d.ts +22 -0
  8. package/dist/adapters/zodAdapter.d.ts.map +1 -0
  9. package/dist/adapters/zodAdapter.js +59 -0
  10. package/dist/core/dateUtils.cjs +69 -0
  11. package/dist/core/dateUtils.d.ts +28 -0
  12. package/dist/core/dateUtils.d.ts.map +1 -0
  13. package/dist/core/dateUtils.js +69 -0
  14. package/dist/core/formStore.cjs +184 -0
  15. package/dist/core/formStore.d.ts +39 -0
  16. package/dist/core/formStore.d.ts.map +1 -0
  17. package/dist/core/formStore.js +184 -0
  18. package/dist/core/numberUtils.cjs +59 -0
  19. package/dist/core/numberUtils.d.ts +26 -0
  20. package/dist/core/numberUtils.d.ts.map +1 -0
  21. package/dist/core/numberUtils.js +59 -0
  22. package/dist/core/pathUtils.cjs +44 -0
  23. package/dist/core/pathUtils.d.ts +15 -0
  24. package/dist/core/pathUtils.d.ts.map +1 -0
  25. package/dist/core/pathUtils.js +44 -0
  26. package/dist/core/payloadUtils.cjs +26 -0
  27. package/dist/core/payloadUtils.d.ts +22 -0
  28. package/dist/core/payloadUtils.d.ts.map +1 -0
  29. package/dist/core/payloadUtils.js +26 -0
  30. package/dist/core/validation.cjs +41 -0
  31. package/dist/core/validation.d.ts +7 -0
  32. package/dist/core/validation.d.ts.map +1 -0
  33. package/dist/core/validation.js +41 -0
  34. package/dist/fields/AutocompleteField/AutocompleteField.cjs +242 -0
  35. package/dist/fields/AutocompleteField/AutocompleteField.d.ts +6 -0
  36. package/dist/fields/AutocompleteField/AutocompleteField.d.ts.map +1 -0
  37. package/dist/fields/AutocompleteField/AutocompleteField.js +242 -0
  38. package/dist/fields/AutocompleteField/AutocompleteField.module.css +168 -0
  39. package/dist/fields/AutocompleteField/AutocompleteField.module.css.cjs +44 -0
  40. package/dist/fields/AutocompleteField/AutocompleteField.module.css.js +44 -0
  41. package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.cjs +286 -0
  42. package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.d.ts +6 -0
  43. package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.d.ts.map +1 -0
  44. package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.js +286 -0
  45. package/dist/fields/AutocompletePredictField/AutocompletePredictField.cjs +289 -0
  46. package/dist/fields/AutocompletePredictField/AutocompletePredictField.d.ts +10 -0
  47. package/dist/fields/AutocompletePredictField/AutocompletePredictField.d.ts.map +1 -0
  48. package/dist/fields/AutocompletePredictField/AutocompletePredictField.js +289 -0
  49. package/dist/fields/CheckboxField/CheckboxField.cjs +60 -0
  50. package/dist/fields/CheckboxField/CheckboxField.d.ts +3 -0
  51. package/dist/fields/CheckboxField/CheckboxField.d.ts.map +1 -0
  52. package/dist/fields/CheckboxField/CheckboxField.js +60 -0
  53. package/dist/fields/CheckboxField/CheckboxField.module.css +29 -0
  54. package/dist/fields/CheckboxField/CheckboxField.module.css.cjs +11 -0
  55. package/dist/fields/CheckboxField/CheckboxField.module.css.js +11 -0
  56. package/dist/fields/ColorField/ColorField.cjs +69 -0
  57. package/dist/fields/ColorField/ColorField.d.ts +3 -0
  58. package/dist/fields/ColorField/ColorField.d.ts.map +1 -0
  59. package/dist/fields/ColorField/ColorField.js +69 -0
  60. package/dist/fields/ColorField/ColorField.module.css +33 -0
  61. package/dist/fields/ColorField/ColorField.module.css.cjs +14 -0
  62. package/dist/fields/ColorField/ColorField.module.css.js +14 -0
  63. package/dist/fields/CurrencyField/CurrencyField.cjs +120 -0
  64. package/dist/fields/CurrencyField/CurrencyField.d.ts +10 -0
  65. package/dist/fields/CurrencyField/CurrencyField.d.ts.map +1 -0
  66. package/dist/fields/CurrencyField/CurrencyField.js +120 -0
  67. package/dist/fields/DateField/DateField.cjs +70 -0
  68. package/dist/fields/DateField/DateField.d.ts +7 -0
  69. package/dist/fields/DateField/DateField.d.ts.map +1 -0
  70. package/dist/fields/DateField/DateField.js +70 -0
  71. package/dist/fields/DateTimeField/DateTimeField.cjs +71 -0
  72. package/dist/fields/DateTimeField/DateTimeField.d.ts +8 -0
  73. package/dist/fields/DateTimeField/DateTimeField.d.ts.map +1 -0
  74. package/dist/fields/DateTimeField/DateTimeField.js +71 -0
  75. package/dist/fields/EmailField/EmailField.cjs +57 -0
  76. package/dist/fields/EmailField/EmailField.d.ts +3 -0
  77. package/dist/fields/EmailField/EmailField.d.ts.map +1 -0
  78. package/dist/fields/EmailField/EmailField.js +57 -0
  79. package/dist/fields/NumberField/NumberField.cjs +110 -0
  80. package/dist/fields/NumberField/NumberField.d.ts +10 -0
  81. package/dist/fields/NumberField/NumberField.d.ts.map +1 -0
  82. package/dist/fields/NumberField/NumberField.js +110 -0
  83. package/dist/fields/PasswordField/PasswordField.cjs +77 -0
  84. package/dist/fields/PasswordField/PasswordField.d.ts +3 -0
  85. package/dist/fields/PasswordField/PasswordField.d.ts.map +1 -0
  86. package/dist/fields/PasswordField/PasswordField.js +77 -0
  87. package/dist/fields/PasswordField/PasswordField.module.css +41 -0
  88. package/dist/fields/PasswordField/PasswordField.module.css.cjs +14 -0
  89. package/dist/fields/PasswordField/PasswordField.module.css.js +14 -0
  90. package/dist/fields/PhoneField/PhoneField.cjs +58 -0
  91. package/dist/fields/PhoneField/PhoneField.d.ts +3 -0
  92. package/dist/fields/PhoneField/PhoneField.d.ts.map +1 -0
  93. package/dist/fields/PhoneField/PhoneField.js +58 -0
  94. package/dist/fields/RadioField/RadioField.cjs +66 -0
  95. package/dist/fields/RadioField/RadioField.d.ts +3 -0
  96. package/dist/fields/RadioField/RadioField.d.ts.map +1 -0
  97. package/dist/fields/RadioField/RadioField.js +66 -0
  98. package/dist/fields/RadioField/RadioField.module.css +34 -0
  99. package/dist/fields/RadioField/RadioField.module.css.cjs +14 -0
  100. package/dist/fields/RadioField/RadioField.module.css.js +14 -0
  101. package/dist/fields/SelectField/SelectField.cjs +58 -0
  102. package/dist/fields/SelectField/SelectField.d.ts +3 -0
  103. package/dist/fields/SelectField/SelectField.d.ts.map +1 -0
  104. package/dist/fields/SelectField/SelectField.js +58 -0
  105. package/dist/fields/SliderField/SliderField.cjs +79 -0
  106. package/dist/fields/SliderField/SliderField.d.ts +7 -0
  107. package/dist/fields/SliderField/SliderField.d.ts.map +1 -0
  108. package/dist/fields/SliderField/SliderField.js +79 -0
  109. package/dist/fields/SliderField/SliderField.module.css +76 -0
  110. package/dist/fields/SliderField/SliderField.module.css.cjs +14 -0
  111. package/dist/fields/SliderField/SliderField.module.css.js +14 -0
  112. package/dist/fields/SwitchField/SwitchField.cjs +65 -0
  113. package/dist/fields/SwitchField/SwitchField.d.ts +3 -0
  114. package/dist/fields/SwitchField/SwitchField.d.ts.map +1 -0
  115. package/dist/fields/SwitchField/SwitchField.js +65 -0
  116. package/dist/fields/SwitchField/SwitchField.module.css +79 -0
  117. package/dist/fields/SwitchField/SwitchField.module.css.cjs +17 -0
  118. package/dist/fields/SwitchField/SwitchField.module.css.js +17 -0
  119. package/dist/fields/TextField/TextField.cjs +56 -0
  120. package/dist/fields/TextField/TextField.d.ts +3 -0
  121. package/dist/fields/TextField/TextField.d.ts.map +1 -0
  122. package/dist/fields/TextField/TextField.js +56 -0
  123. package/dist/fields/TextareaField/TextareaField.cjs +57 -0
  124. package/dist/fields/TextareaField/TextareaField.d.ts +5 -0
  125. package/dist/fields/TextareaField/TextareaField.d.ts.map +1 -0
  126. package/dist/fields/TextareaField/TextareaField.js +57 -0
  127. package/dist/fields/TimeField/TimeField.cjs +67 -0
  128. package/dist/fields/TimeField/TimeField.d.ts +6 -0
  129. package/dist/fields/TimeField/TimeField.d.ts.map +1 -0
  130. package/dist/fields/TimeField/TimeField.js +67 -0
  131. package/dist/fields/defaultComponentMap.cjs +43 -0
  132. package/dist/fields/defaultComponentMap.d.ts +7 -0
  133. package/dist/fields/defaultComponentMap.d.ts.map +1 -0
  134. package/dist/fields/defaultComponentMap.js +43 -0
  135. package/dist/fields/fieldBase.module.css +201 -0
  136. package/dist/fields/fieldBase.module.css.cjs +50 -0
  137. package/dist/fields/fieldBase.module.css.js +50 -0
  138. package/dist/fields/fieldUtils.cjs +26 -0
  139. package/dist/fields/fieldUtils.d.ts +24 -0
  140. package/dist/fields/fieldUtils.d.ts.map +1 -0
  141. package/dist/fields/fieldUtils.js +26 -0
  142. package/dist/index.cjs +99 -0
  143. package/dist/index.d.ts +42 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +99 -0
  146. package/dist/layout/Box/Box.cjs +70 -0
  147. package/dist/layout/Box/Box.d.ts +6 -0
  148. package/dist/layout/Box/Box.d.ts.map +1 -0
  149. package/dist/layout/Box/Box.js +70 -0
  150. package/dist/layout/Box/Box.module.css +3 -0
  151. package/dist/layout/Box/Box.module.css.cjs +8 -0
  152. package/dist/layout/Box/Box.module.css.js +8 -0
  153. package/dist/layout/Divider/Divider.cjs +20 -0
  154. package/dist/layout/Divider/Divider.d.ts +6 -0
  155. package/dist/layout/Divider/Divider.d.ts.map +1 -0
  156. package/dist/layout/Divider/Divider.js +20 -0
  157. package/dist/layout/Divider/Divider.module.css +25 -0
  158. package/dist/layout/Divider/Divider.module.css.cjs +14 -0
  159. package/dist/layout/Divider/Divider.module.css.js +14 -0
  160. package/dist/layout/Grid/Grid.cjs +106 -0
  161. package/dist/layout/Grid/Grid.d.ts +7 -0
  162. package/dist/layout/Grid/Grid.d.ts.map +1 -0
  163. package/dist/layout/Grid/Grid.js +106 -0
  164. package/dist/layout/Grid/Grid.module.css +43 -0
  165. package/dist/layout/Grid/Grid.module.css.cjs +23 -0
  166. package/dist/layout/Grid/Grid.module.css.js +23 -0
  167. package/dist/layout/Spacer/Spacer.cjs +30 -0
  168. package/dist/layout/Spacer/Spacer.d.ts +21 -0
  169. package/dist/layout/Spacer/Spacer.d.ts.map +1 -0
  170. package/dist/layout/Spacer/Spacer.js +30 -0
  171. package/dist/layout/Stack/Stack.cjs +52 -0
  172. package/dist/layout/Stack/Stack.d.ts +7 -0
  173. package/dist/layout/Stack/Stack.d.ts.map +1 -0
  174. package/dist/layout/Stack/Stack.js +52 -0
  175. package/dist/layout/Stack/Stack.module.css +3 -0
  176. package/dist/layout/Stack/Stack.module.css.cjs +8 -0
  177. package/dist/layout/Stack/Stack.module.css.js +8 -0
  178. package/dist/layout/index.d.ts +6 -0
  179. package/dist/layout/index.d.ts.map +1 -0
  180. package/dist/react/AxenArrayField.cjs +80 -0
  181. package/dist/react/AxenArrayField.d.ts +15 -0
  182. package/dist/react/AxenArrayField.d.ts.map +1 -0
  183. package/dist/react/AxenArrayField.js +80 -0
  184. package/dist/react/AxenField.cjs +62 -0
  185. package/dist/react/AxenField.d.ts +13 -0
  186. package/dist/react/AxenField.d.ts.map +1 -0
  187. package/dist/react/AxenField.js +62 -0
  188. package/dist/react/AxenForm.cjs +134 -0
  189. package/dist/react/AxenForm.d.ts +7 -0
  190. package/dist/react/AxenForm.d.ts.map +1 -0
  191. package/dist/react/AxenForm.js +134 -0
  192. package/dist/react/FormContext.cjs +13 -0
  193. package/dist/react/FormContext.d.ts +11 -0
  194. package/dist/react/FormContext.d.ts.map +1 -0
  195. package/dist/react/FormContext.js +13 -0
  196. package/dist/react/useAxenForm.cjs +88 -0
  197. package/dist/react/useAxenForm.d.ts +8 -0
  198. package/dist/react/useAxenForm.d.ts.map +1 -0
  199. package/dist/react/useAxenForm.js +88 -0
  200. package/dist/react/useField.cjs +41 -0
  201. package/dist/react/useField.d.ts +13 -0
  202. package/dist/react/useField.d.ts.map +1 -0
  203. package/dist/react/useField.js +41 -0
  204. package/dist/react/useFieldArray.cjs +74 -0
  205. package/dist/react/useFieldArray.d.ts +5 -0
  206. package/dist/react/useFieldArray.d.ts.map +1 -0
  207. package/dist/react/useFieldArray.js +74 -0
  208. package/dist/types.d.ts +226 -0
  209. package/dist/types.d.ts.map +1 -0
  210. package/package.json +87 -0
@@ -0,0 +1,289 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const AutocompleteField_module = require("../AutocompleteField/AutocompleteField.module.css.cjs");
6
+ const fieldBase_module = require("../fieldBase.module.css.cjs");
7
+ const fieldUtils = require("../fieldUtils.cjs");
8
+ const DEBOUNCE_MS = 400;
9
+ function AutocompletePredictField({
10
+ name,
11
+ value,
12
+ onChange: _onChange,
13
+ onBlur,
14
+ error,
15
+ helperText,
16
+ label,
17
+ placeholder,
18
+ disabled,
19
+ readOnly,
20
+ required,
21
+ options: staticOptions,
22
+ fetchOptions,
23
+ optionLabel,
24
+ form
25
+ }) {
26
+ const [inputText, setInputText] = react.useState("");
27
+ const [filteredOptions, setFilteredOptions] = react.useState([]);
28
+ const [isOpen, setIsOpen] = react.useState(false);
29
+ const [activeIndex, setActiveIndex] = react.useState(-1);
30
+ const [loading, setLoading] = react.useState(false);
31
+ const [ghostText, setGhostText] = react.useState("");
32
+ const abortRef = react.useRef(null);
33
+ const debounceRef = react.useRef(void 0);
34
+ const wrapperRef = react.useRef(null);
35
+ const measureRef = react.useRef(null);
36
+ const getOptionLabel = react.useCallback(
37
+ (opt) => {
38
+ if (optionLabel) {
39
+ const val = opt[optionLabel];
40
+ return typeof val === "string" || typeof val === "number" ? String(val) : opt.label;
41
+ }
42
+ return opt.label;
43
+ },
44
+ [optionLabel]
45
+ );
46
+ react.useEffect(() => {
47
+ if (value != null && value !== "") {
48
+ const allOpts = staticOptions ?? filteredOptions;
49
+ const match = allOpts.find((o) => o.value === value);
50
+ if (match) {
51
+ setInputText(getOptionLabel(match));
52
+ setGhostText("");
53
+ }
54
+ } else {
55
+ setInputText("");
56
+ }
57
+ }, [value]);
58
+ const updateGhost = react.useCallback(
59
+ (query, opts) => {
60
+ if (!query || opts.length === 0) {
61
+ setGhostText("");
62
+ return;
63
+ }
64
+ const firstLabel = getOptionLabel(opts[0]);
65
+ if (firstLabel.toLowerCase().startsWith(query.toLowerCase())) {
66
+ setGhostText(query + firstLabel.slice(query.length));
67
+ } else {
68
+ setGhostText("");
69
+ }
70
+ },
71
+ [getOptionLabel]
72
+ );
73
+ const doSearch = react.useCallback(
74
+ (query) => {
75
+ var _a;
76
+ if (fetchOptions) {
77
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
78
+ const controller = new AbortController();
79
+ abortRef.current = controller;
80
+ setLoading(true);
81
+ fetchOptions(query, controller.signal).then((results) => {
82
+ if (!controller.signal.aborted) {
83
+ setFilteredOptions(results);
84
+ updateGhost(query, results);
85
+ setLoading(false);
86
+ }
87
+ }).catch((err) => {
88
+ if (!controller.signal.aborted && err.name !== "AbortError") {
89
+ setFilteredOptions([]);
90
+ setGhostText("");
91
+ setLoading(false);
92
+ }
93
+ });
94
+ } else {
95
+ const q = query.toLowerCase();
96
+ const filtered = (staticOptions ?? []).filter(
97
+ (opt) => getOptionLabel(opt).toLowerCase().includes(q)
98
+ );
99
+ setFilteredOptions(filtered);
100
+ updateGhost(query, filtered);
101
+ }
102
+ },
103
+ [fetchOptions, staticOptions, getOptionLabel, updateGhost]
104
+ );
105
+ const handleInputChange = react.useCallback(
106
+ (e) => {
107
+ const query = e.target.value;
108
+ setInputText(query);
109
+ setIsOpen(true);
110
+ setActiveIndex(-1);
111
+ form.setFieldValue(name, "");
112
+ clearTimeout(debounceRef.current);
113
+ debounceRef.current = setTimeout(() => doSearch(query), DEBOUNCE_MS);
114
+ },
115
+ [form, name, doSearch]
116
+ );
117
+ const selectOption = react.useCallback(
118
+ (opt) => {
119
+ form.setFieldValue(name, opt.value);
120
+ setInputText(getOptionLabel(opt));
121
+ setGhostText("");
122
+ setIsOpen(false);
123
+ setActiveIndex(-1);
124
+ },
125
+ [form, name, getOptionLabel]
126
+ );
127
+ const handleKeyDown = react.useCallback(
128
+ (e) => {
129
+ if (e.key === "Tab" && ghostText && ghostText !== inputText) {
130
+ e.preventDefault();
131
+ setInputText(ghostText);
132
+ const match = filteredOptions.find(
133
+ (o) => getOptionLabel(o).toLowerCase() === ghostText.toLowerCase()
134
+ );
135
+ if (match) {
136
+ form.setFieldValue(name, match.value);
137
+ }
138
+ setGhostText("");
139
+ setIsOpen(false);
140
+ return;
141
+ }
142
+ if (!isOpen) {
143
+ if (e.key === "ArrowDown") {
144
+ setIsOpen(true);
145
+ doSearch(inputText);
146
+ }
147
+ return;
148
+ }
149
+ switch (e.key) {
150
+ case "ArrowDown":
151
+ e.preventDefault();
152
+ setActiveIndex((prev) => Math.min(prev + 1, filteredOptions.length - 1));
153
+ break;
154
+ case "ArrowUp":
155
+ e.preventDefault();
156
+ setActiveIndex((prev) => Math.max(prev - 1, 0));
157
+ break;
158
+ case "Enter":
159
+ e.preventDefault();
160
+ if (activeIndex >= 0 && filteredOptions[activeIndex]) {
161
+ selectOption(filteredOptions[activeIndex]);
162
+ }
163
+ break;
164
+ case "Escape":
165
+ setIsOpen(false);
166
+ setGhostText("");
167
+ setActiveIndex(-1);
168
+ break;
169
+ }
170
+ },
171
+ [
172
+ isOpen,
173
+ activeIndex,
174
+ filteredOptions,
175
+ inputText,
176
+ ghostText,
177
+ selectOption,
178
+ doSearch,
179
+ form,
180
+ name,
181
+ getOptionLabel
182
+ ]
183
+ );
184
+ const handleBlur = react.useCallback(
185
+ (e) => {
186
+ setTimeout(() => {
187
+ var _a;
188
+ if (!((_a = wrapperRef.current) == null ? void 0 : _a.contains(document.activeElement))) {
189
+ setIsOpen(false);
190
+ onBlur(e);
191
+ }
192
+ }, 150);
193
+ },
194
+ [onBlur]
195
+ );
196
+ react.useEffect(() => {
197
+ return () => {
198
+ var _a;
199
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
200
+ clearTimeout(debounceRef.current);
201
+ };
202
+ }, []);
203
+ const aria = fieldUtils.ariaProps(name, { error, helperText, required, label });
204
+ const listboxId = `${name}-listbox`;
205
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: fieldBase_module.default.wrapper, ref: wrapperRef, children: [
206
+ label && /* @__PURE__ */ jsxRuntime.jsx(
207
+ "label",
208
+ {
209
+ id: fieldUtils.labelId(name),
210
+ htmlFor: name,
211
+ className: fieldUtils.cx(fieldBase_module.default.label, required && fieldBase_module.default.labelRequired),
212
+ children: label
213
+ }
214
+ ),
215
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: AutocompleteField_module.default.predictWrap, children: [
216
+ ghostText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: AutocompleteField_module.default.ghostText, "aria-hidden": "true", children: ghostText }),
217
+ /* @__PURE__ */ jsxRuntime.jsx("span", { ref: measureRef, className: AutocompleteField_module.default.ghostHidden, "aria-hidden": "true", children: inputText }),
218
+ /* @__PURE__ */ jsxRuntime.jsx(
219
+ "input",
220
+ {
221
+ ...aria,
222
+ type: "text",
223
+ name,
224
+ value: inputText,
225
+ onChange: handleInputChange,
226
+ onKeyDown: handleKeyDown,
227
+ onBlur: handleBlur,
228
+ onFocus: () => {
229
+ if (inputText) {
230
+ doSearch(inputText);
231
+ }
232
+ setIsOpen(true);
233
+ },
234
+ placeholder,
235
+ disabled,
236
+ readOnly,
237
+ role: "combobox",
238
+ "aria-expanded": isOpen,
239
+ "aria-controls": listboxId,
240
+ "aria-activedescendant": activeIndex >= 0 ? `${name}-opt-${activeIndex}` : void 0,
241
+ "aria-autocomplete": "both",
242
+ autoComplete: "off",
243
+ className: fieldUtils.cx(fieldBase_module.default.input, error && fieldBase_module.default.inputError),
244
+ style: { background: "transparent", position: "relative", zIndex: 1 }
245
+ }
246
+ ),
247
+ loading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: AutocompleteField_module.default.spinner, "aria-hidden": "true" })
248
+ ] }),
249
+ isOpen && filteredOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
250
+ "div",
251
+ {
252
+ id: listboxId,
253
+ role: "listbox",
254
+ className: AutocompleteField_module.default.dropdown,
255
+ children: filteredOptions.map((opt, i) => /* @__PURE__ */ jsxRuntime.jsx(
256
+ "div",
257
+ {
258
+ id: `${name}-opt-${i}`,
259
+ role: "option",
260
+ tabIndex: -1,
261
+ "aria-selected": i === activeIndex,
262
+ "aria-disabled": opt.disabled,
263
+ className: fieldUtils.cx(
264
+ AutocompleteField_module.default.option,
265
+ i === activeIndex && AutocompleteField_module.default.optionActive,
266
+ opt.disabled && AutocompleteField_module.default.optionDisabled
267
+ ),
268
+ onMouseDown: (e) => {
269
+ e.preventDefault();
270
+ if (!opt.disabled) selectOption(opt);
271
+ },
272
+ children: getOptionLabel(opt)
273
+ },
274
+ opt.value
275
+ ))
276
+ }
277
+ ),
278
+ helperText && /* @__PURE__ */ jsxRuntime.jsx(
279
+ "span",
280
+ {
281
+ id: fieldUtils.helperId(name),
282
+ className: fieldUtils.cx(fieldBase_module.default.helperText, error && fieldBase_module.default.helperTextError),
283
+ role: error ? "alert" : void 0,
284
+ children: helperText
285
+ }
286
+ )
287
+ ] });
288
+ }
289
+ exports.AutocompletePredictField = AutocompletePredictField;
@@ -0,0 +1,10 @@
1
+ import { AutocompleteOption, FieldComponentProps } from '../../types';
2
+ /**
3
+ * Autocomplete with predictive ghost text.
4
+ * Shows a faded suggestion that can be accepted with Tab.
5
+ */
6
+ export declare function AutocompletePredictField({ name, value, onChange: _onChange, onBlur, error, helperText, label, placeholder, disabled, readOnly, required, options: staticOptions, fetchOptions, optionLabel, form, }: FieldComponentProps & {
7
+ fetchOptions?: (query: string, signal?: AbortSignal) => Promise<AutocompleteOption[]>;
8
+ optionLabel?: string;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=AutocompletePredictField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutocompletePredictField.d.ts","sourceRoot":"","sources":["../../../src/fields/AutocompletePredictField/AutocompletePredictField.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAO3E;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,IAAI,EACJ,KAAK,EACL,QAAQ,EAAE,SAAS,EACnB,MAAM,EACN,KAAK,EACL,UAAU,EACV,KAAK,EACL,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,OAAO,EAAE,aAAa,EACtB,YAAY,EACZ,WAAW,EACX,IAAI,GACL,EAAE,mBAAmB,GAAG;IACvB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,2CAiSA"}
@@ -0,0 +1,289 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useRef, useCallback, useEffect } from "react";
3
+ import localStyles from "../AutocompleteField/AutocompleteField.module.css.js";
4
+ import styles from "../fieldBase.module.css.js";
5
+ import { ariaProps, cx, labelId, helperId } from "../fieldUtils.js";
6
+ const DEBOUNCE_MS = 400;
7
+ function AutocompletePredictField({
8
+ name,
9
+ value,
10
+ onChange: _onChange,
11
+ onBlur,
12
+ error,
13
+ helperText,
14
+ label,
15
+ placeholder,
16
+ disabled,
17
+ readOnly,
18
+ required,
19
+ options: staticOptions,
20
+ fetchOptions,
21
+ optionLabel,
22
+ form
23
+ }) {
24
+ const [inputText, setInputText] = useState("");
25
+ const [filteredOptions, setFilteredOptions] = useState([]);
26
+ const [isOpen, setIsOpen] = useState(false);
27
+ const [activeIndex, setActiveIndex] = useState(-1);
28
+ const [loading, setLoading] = useState(false);
29
+ const [ghostText, setGhostText] = useState("");
30
+ const abortRef = useRef(null);
31
+ const debounceRef = useRef(void 0);
32
+ const wrapperRef = useRef(null);
33
+ const measureRef = useRef(null);
34
+ const getOptionLabel = useCallback(
35
+ (opt) => {
36
+ if (optionLabel) {
37
+ const val = opt[optionLabel];
38
+ return typeof val === "string" || typeof val === "number" ? String(val) : opt.label;
39
+ }
40
+ return opt.label;
41
+ },
42
+ [optionLabel]
43
+ );
44
+ useEffect(() => {
45
+ if (value != null && value !== "") {
46
+ const allOpts = staticOptions ?? filteredOptions;
47
+ const match = allOpts.find((o) => o.value === value);
48
+ if (match) {
49
+ setInputText(getOptionLabel(match));
50
+ setGhostText("");
51
+ }
52
+ } else {
53
+ setInputText("");
54
+ }
55
+ }, [value]);
56
+ const updateGhost = useCallback(
57
+ (query, opts) => {
58
+ if (!query || opts.length === 0) {
59
+ setGhostText("");
60
+ return;
61
+ }
62
+ const firstLabel = getOptionLabel(opts[0]);
63
+ if (firstLabel.toLowerCase().startsWith(query.toLowerCase())) {
64
+ setGhostText(query + firstLabel.slice(query.length));
65
+ } else {
66
+ setGhostText("");
67
+ }
68
+ },
69
+ [getOptionLabel]
70
+ );
71
+ const doSearch = useCallback(
72
+ (query) => {
73
+ var _a;
74
+ if (fetchOptions) {
75
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
76
+ const controller = new AbortController();
77
+ abortRef.current = controller;
78
+ setLoading(true);
79
+ fetchOptions(query, controller.signal).then((results) => {
80
+ if (!controller.signal.aborted) {
81
+ setFilteredOptions(results);
82
+ updateGhost(query, results);
83
+ setLoading(false);
84
+ }
85
+ }).catch((err) => {
86
+ if (!controller.signal.aborted && err.name !== "AbortError") {
87
+ setFilteredOptions([]);
88
+ setGhostText("");
89
+ setLoading(false);
90
+ }
91
+ });
92
+ } else {
93
+ const q = query.toLowerCase();
94
+ const filtered = (staticOptions ?? []).filter(
95
+ (opt) => getOptionLabel(opt).toLowerCase().includes(q)
96
+ );
97
+ setFilteredOptions(filtered);
98
+ updateGhost(query, filtered);
99
+ }
100
+ },
101
+ [fetchOptions, staticOptions, getOptionLabel, updateGhost]
102
+ );
103
+ const handleInputChange = useCallback(
104
+ (e) => {
105
+ const query = e.target.value;
106
+ setInputText(query);
107
+ setIsOpen(true);
108
+ setActiveIndex(-1);
109
+ form.setFieldValue(name, "");
110
+ clearTimeout(debounceRef.current);
111
+ debounceRef.current = setTimeout(() => doSearch(query), DEBOUNCE_MS);
112
+ },
113
+ [form, name, doSearch]
114
+ );
115
+ const selectOption = useCallback(
116
+ (opt) => {
117
+ form.setFieldValue(name, opt.value);
118
+ setInputText(getOptionLabel(opt));
119
+ setGhostText("");
120
+ setIsOpen(false);
121
+ setActiveIndex(-1);
122
+ },
123
+ [form, name, getOptionLabel]
124
+ );
125
+ const handleKeyDown = useCallback(
126
+ (e) => {
127
+ if (e.key === "Tab" && ghostText && ghostText !== inputText) {
128
+ e.preventDefault();
129
+ setInputText(ghostText);
130
+ const match = filteredOptions.find(
131
+ (o) => getOptionLabel(o).toLowerCase() === ghostText.toLowerCase()
132
+ );
133
+ if (match) {
134
+ form.setFieldValue(name, match.value);
135
+ }
136
+ setGhostText("");
137
+ setIsOpen(false);
138
+ return;
139
+ }
140
+ if (!isOpen) {
141
+ if (e.key === "ArrowDown") {
142
+ setIsOpen(true);
143
+ doSearch(inputText);
144
+ }
145
+ return;
146
+ }
147
+ switch (e.key) {
148
+ case "ArrowDown":
149
+ e.preventDefault();
150
+ setActiveIndex((prev) => Math.min(prev + 1, filteredOptions.length - 1));
151
+ break;
152
+ case "ArrowUp":
153
+ e.preventDefault();
154
+ setActiveIndex((prev) => Math.max(prev - 1, 0));
155
+ break;
156
+ case "Enter":
157
+ e.preventDefault();
158
+ if (activeIndex >= 0 && filteredOptions[activeIndex]) {
159
+ selectOption(filteredOptions[activeIndex]);
160
+ }
161
+ break;
162
+ case "Escape":
163
+ setIsOpen(false);
164
+ setGhostText("");
165
+ setActiveIndex(-1);
166
+ break;
167
+ }
168
+ },
169
+ [
170
+ isOpen,
171
+ activeIndex,
172
+ filteredOptions,
173
+ inputText,
174
+ ghostText,
175
+ selectOption,
176
+ doSearch,
177
+ form,
178
+ name,
179
+ getOptionLabel
180
+ ]
181
+ );
182
+ const handleBlur = useCallback(
183
+ (e) => {
184
+ setTimeout(() => {
185
+ var _a;
186
+ if (!((_a = wrapperRef.current) == null ? void 0 : _a.contains(document.activeElement))) {
187
+ setIsOpen(false);
188
+ onBlur(e);
189
+ }
190
+ }, 150);
191
+ },
192
+ [onBlur]
193
+ );
194
+ useEffect(() => {
195
+ return () => {
196
+ var _a;
197
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
198
+ clearTimeout(debounceRef.current);
199
+ };
200
+ }, []);
201
+ const aria = ariaProps(name, { error, helperText, required, label });
202
+ const listboxId = `${name}-listbox`;
203
+ return /* @__PURE__ */ jsxs("div", { className: styles.wrapper, ref: wrapperRef, children: [
204
+ label && /* @__PURE__ */ jsx(
205
+ "label",
206
+ {
207
+ id: labelId(name),
208
+ htmlFor: name,
209
+ className: cx(styles.label, required && styles.labelRequired),
210
+ children: label
211
+ }
212
+ ),
213
+ /* @__PURE__ */ jsxs("div", { className: localStyles.predictWrap, children: [
214
+ ghostText && /* @__PURE__ */ jsx("span", { className: localStyles.ghostText, "aria-hidden": "true", children: ghostText }),
215
+ /* @__PURE__ */ jsx("span", { ref: measureRef, className: localStyles.ghostHidden, "aria-hidden": "true", children: inputText }),
216
+ /* @__PURE__ */ jsx(
217
+ "input",
218
+ {
219
+ ...aria,
220
+ type: "text",
221
+ name,
222
+ value: inputText,
223
+ onChange: handleInputChange,
224
+ onKeyDown: handleKeyDown,
225
+ onBlur: handleBlur,
226
+ onFocus: () => {
227
+ if (inputText) {
228
+ doSearch(inputText);
229
+ }
230
+ setIsOpen(true);
231
+ },
232
+ placeholder,
233
+ disabled,
234
+ readOnly,
235
+ role: "combobox",
236
+ "aria-expanded": isOpen,
237
+ "aria-controls": listboxId,
238
+ "aria-activedescendant": activeIndex >= 0 ? `${name}-opt-${activeIndex}` : void 0,
239
+ "aria-autocomplete": "both",
240
+ autoComplete: "off",
241
+ className: cx(styles.input, error && styles.inputError),
242
+ style: { background: "transparent", position: "relative", zIndex: 1 }
243
+ }
244
+ ),
245
+ loading && /* @__PURE__ */ jsx("span", { className: localStyles.spinner, "aria-hidden": "true" })
246
+ ] }),
247
+ isOpen && filteredOptions.length > 0 && /* @__PURE__ */ jsx(
248
+ "div",
249
+ {
250
+ id: listboxId,
251
+ role: "listbox",
252
+ className: localStyles.dropdown,
253
+ children: filteredOptions.map((opt, i) => /* @__PURE__ */ jsx(
254
+ "div",
255
+ {
256
+ id: `${name}-opt-${i}`,
257
+ role: "option",
258
+ tabIndex: -1,
259
+ "aria-selected": i === activeIndex,
260
+ "aria-disabled": opt.disabled,
261
+ className: cx(
262
+ localStyles.option,
263
+ i === activeIndex && localStyles.optionActive,
264
+ opt.disabled && localStyles.optionDisabled
265
+ ),
266
+ onMouseDown: (e) => {
267
+ e.preventDefault();
268
+ if (!opt.disabled) selectOption(opt);
269
+ },
270
+ children: getOptionLabel(opt)
271
+ },
272
+ opt.value
273
+ ))
274
+ }
275
+ ),
276
+ helperText && /* @__PURE__ */ jsx(
277
+ "span",
278
+ {
279
+ id: helperId(name),
280
+ className: cx(styles.helperText, error && styles.helperTextError),
281
+ role: error ? "alert" : void 0,
282
+ children: helperText
283
+ }
284
+ )
285
+ ] });
286
+ }
287
+ export {
288
+ AutocompletePredictField
289
+ };
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const fieldBase_module = require("../fieldBase.module.css.cjs");
6
+ const fieldUtils = require("../fieldUtils.cjs");
7
+ const CheckboxField_module = require("./CheckboxField.module.css.cjs");
8
+ function CheckboxField({
9
+ name,
10
+ value,
11
+ onChange: _onChange,
12
+ onBlur,
13
+ error,
14
+ helperText,
15
+ label,
16
+ disabled,
17
+ readOnly,
18
+ required,
19
+ form
20
+ }) {
21
+ const checked = Boolean(value);
22
+ const handleChange = react.useCallback(
23
+ (e) => {
24
+ if (readOnly) return;
25
+ form.setFieldValue(name, e.target.checked);
26
+ },
27
+ [form, name, readOnly]
28
+ );
29
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: fieldBase_module.default.wrapper, children: [
30
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: fieldUtils.cx(fieldBase_module.default.inlineWrapper, CheckboxField_module.default.checkboxLabel), children: [
31
+ /* @__PURE__ */ jsxRuntime.jsx(
32
+ "input",
33
+ {
34
+ type: "checkbox",
35
+ id: name,
36
+ name,
37
+ checked,
38
+ onChange: handleChange,
39
+ onBlur,
40
+ disabled,
41
+ "aria-invalid": error || void 0,
42
+ "aria-describedby": helperText ? fieldUtils.helperId(name) : void 0,
43
+ "aria-required": required || void 0,
44
+ className: CheckboxField_module.default.checkbox
45
+ }
46
+ ),
47
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: fieldBase_module.default.inlineLabel, children: label })
48
+ ] }),
49
+ helperText && /* @__PURE__ */ jsxRuntime.jsx(
50
+ "span",
51
+ {
52
+ id: fieldUtils.helperId(name),
53
+ className: fieldUtils.cx(fieldBase_module.default.helperText, error && fieldBase_module.default.helperTextError),
54
+ role: error ? "alert" : void 0,
55
+ children: helperText
56
+ }
57
+ )
58
+ ] });
59
+ }
60
+ exports.CheckboxField = CheckboxField;
@@ -0,0 +1,3 @@
1
+ import { FieldComponentProps } from '../../types';
2
+ export declare function CheckboxField({ name, value, onChange: _onChange, onBlur, error, helperText, label, disabled, readOnly, required, form, }: Readonly<FieldComponentProps>): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=CheckboxField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckboxField.d.ts","sourceRoot":"","sources":["../../../src/fields/CheckboxField/CheckboxField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAKvD,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,QAAQ,EAAE,SAAS,EACnB,MAAM,EACN,KAAK,EACL,UAAU,EACV,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,QAAQ,CAAC,mBAAmB,CAAC,2CAwC/B"}