@react-fabric/form 1.0.0-beta.6 → 1.0.0-beta.61

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 (187) hide show
  1. package/{src/input/ArrayInput.module.css → css/_arrayInput.css} +8 -8
  2. package/css/_colorPicker.css +65 -0
  3. package/{src/internal/Field.module.css → css/_field.css} +66 -30
  4. package/{src/input/File.module.css → css/_file.css} +21 -6
  5. package/css/styles.css +27 -0
  6. package/dist/cjs/builder/FileField.js +40 -28
  7. package/dist/cjs/builder/FormField.js +50 -34
  8. package/dist/cjs/builder/SchemaEditor.js +72 -0
  9. package/dist/cjs/builder/components/AddSchemaFields.js +63 -0
  10. package/dist/cjs/builder/components/SchemaArrayForm.js +145 -0
  11. package/dist/cjs/builder/components/SchemaField.js +414 -0
  12. package/dist/cjs/form/Controller.js +46 -1
  13. package/dist/cjs/form/Form.js +71 -13
  14. package/dist/cjs/hooks/useFileUploader.js +16 -0
  15. package/dist/cjs/hooks/useFormBuilder.js +67 -18
  16. package/dist/cjs/i18n/ar.json.js +5 -4
  17. package/dist/cjs/i18n/en.json.js +5 -5
  18. package/dist/cjs/index.js +12 -2
  19. package/dist/cjs/input/ArrayInput.js +128 -38
  20. package/dist/cjs/input/AvatarInput.js +43 -23
  21. package/dist/cjs/input/Checkbox.js +18 -8
  22. package/dist/cjs/input/ColorInput.js +114 -59
  23. package/dist/cjs/input/ColorPicker.js +60 -76
  24. package/dist/cjs/input/DateInput.js +197 -0
  25. package/dist/cjs/input/Field.js +10 -4
  26. package/dist/cjs/input/File.js +15 -8
  27. package/dist/cjs/input/Hidden.js +13 -2
  28. package/dist/cjs/input/Input.js +24 -10
  29. package/dist/cjs/input/Number.js +22 -10
  30. package/dist/cjs/input/Password.js +23 -13
  31. package/dist/cjs/input/Radio.js +14 -5
  32. package/dist/cjs/input/RadioGroup.js +10 -1
  33. package/dist/cjs/input/{Range.js → RangeSlider.js} +16 -8
  34. package/dist/cjs/input/Search.js +32 -22
  35. package/dist/cjs/input/Slider.js +12 -6
  36. package/dist/cjs/input/Switch.js +20 -9
  37. package/dist/cjs/input/Textarea.js +29 -8
  38. package/dist/cjs/internal/ErrorIcon.js +2 -2
  39. package/dist/cjs/internal/FieldWrapper.js +11 -4
  40. package/dist/cjs/internal/InputWrapper.js +29 -22
  41. package/dist/cjs/select/AutoComplete.js +22 -13
  42. package/dist/cjs/select/DualList.js +34 -12
  43. package/dist/cjs/select/List.js +49 -21
  44. package/dist/cjs/select/Options.js +49 -42
  45. package/dist/cjs/select/Select.js +21 -10
  46. package/dist/cjs/select/useSelect.js +22 -11
  47. package/dist/cjs/types/schema.js +43 -0
  48. package/dist/cjs/utils/eventHandlers.js +15 -5
  49. package/dist/esm/builder/FileField.js +42 -30
  50. package/dist/esm/builder/FormField.js +50 -34
  51. package/dist/esm/builder/SchemaEditor.js +72 -0
  52. package/dist/esm/builder/components/AddSchemaFields.js +63 -0
  53. package/dist/esm/builder/components/SchemaArrayForm.js +145 -0
  54. package/dist/esm/builder/components/SchemaField.js +414 -0
  55. package/dist/esm/form/Controller.js +46 -1
  56. package/dist/esm/form/Form.js +73 -16
  57. package/dist/esm/hooks/useFileUploader.js +16 -0
  58. package/dist/esm/hooks/useFormBuilder.js +65 -16
  59. package/dist/esm/i18n/ar.json.js +5 -4
  60. package/dist/esm/i18n/en.json.js +5 -5
  61. package/dist/esm/index.js +6 -2
  62. package/dist/esm/input/ArrayInput.js +128 -38
  63. package/dist/esm/input/AvatarInput.js +43 -23
  64. package/dist/esm/input/Checkbox.js +19 -9
  65. package/dist/esm/input/ColorInput.js +116 -61
  66. package/dist/esm/input/ColorPicker.js +60 -76
  67. package/dist/esm/input/DateInput.js +197 -0
  68. package/dist/esm/input/Field.js +11 -5
  69. package/dist/esm/input/File.js +18 -11
  70. package/dist/esm/input/Hidden.js +13 -2
  71. package/dist/esm/input/Input.js +26 -12
  72. package/dist/esm/input/Number.js +24 -12
  73. package/dist/esm/input/Password.js +26 -16
  74. package/dist/esm/input/Radio.js +15 -6
  75. package/dist/esm/input/RadioGroup.js +11 -2
  76. package/dist/esm/input/{Range.js → RangeSlider.js} +16 -8
  77. package/dist/esm/input/Search.js +35 -25
  78. package/dist/esm/input/Slider.js +12 -6
  79. package/dist/esm/input/Switch.js +20 -9
  80. package/dist/esm/input/Textarea.js +30 -9
  81. package/dist/esm/internal/ErrorIcon.js +3 -3
  82. package/dist/esm/internal/FieldWrapper.js +11 -4
  83. package/dist/esm/internal/InputWrapper.js +30 -23
  84. package/dist/esm/select/AutoComplete.js +23 -14
  85. package/dist/esm/select/DualList.js +35 -13
  86. package/dist/esm/select/List.js +50 -22
  87. package/dist/esm/select/Options.js +49 -42
  88. package/dist/esm/select/Select.js +22 -11
  89. package/dist/esm/select/useSelect.js +23 -12
  90. package/{src/input/ColorPicker.module.css → dist/esm/types/schema.js} +18 -27
  91. package/dist/esm/utils/eventHandlers.js +15 -5
  92. package/dist/types/builder/FileField.d.ts +4 -2
  93. package/dist/types/builder/FormField.d.ts +3 -1
  94. package/dist/types/builder/SchemaEditor.d.ts +9 -0
  95. package/dist/types/builder/components/AddSchemaFields.d.ts +2 -0
  96. package/dist/types/builder/components/SchemaArrayForm.d.ts +2 -0
  97. package/dist/types/builder/components/SchemaField.d.ts +10 -0
  98. package/dist/types/form/Controller.d.ts +47 -2
  99. package/dist/types/form/Form.d.ts +49 -6
  100. package/dist/types/hooks/useFileUploader.d.ts +16 -0
  101. package/dist/types/hooks/useFormBuilder.d.ts +38 -1
  102. package/dist/types/index.d.ts +6 -3
  103. package/dist/types/input/ArrayInput.d.ts +69 -12
  104. package/dist/types/input/AvatarInput.d.ts +23 -3
  105. package/dist/types/input/Checkbox.d.ts +13 -4
  106. package/dist/types/input/ColorInput.d.ts +15 -2
  107. package/dist/types/input/ColorPicker.d.ts +11 -1
  108. package/dist/types/input/DateInput.d.ts +28 -0
  109. package/dist/types/input/Field.d.ts +5 -1
  110. package/dist/types/input/File.d.ts +9 -0
  111. package/dist/types/input/Hidden.d.ts +13 -1
  112. package/dist/types/input/Input.d.ts +9 -1
  113. package/dist/types/input/Number.d.ts +9 -1
  114. package/dist/types/input/Password.d.ts +7 -1
  115. package/dist/types/input/Radio.d.ts +9 -1
  116. package/dist/types/input/RadioGroup.d.ts +8 -1
  117. package/dist/types/input/RangeSlider.d.ts +67 -0
  118. package/dist/types/input/Search.d.ts +14 -1
  119. package/dist/types/input/Slider.d.ts +8 -2
  120. package/dist/types/input/Switch.d.ts +10 -2
  121. package/dist/types/input/Textarea.d.ts +15 -1
  122. package/dist/types/internal/FieldWrapper.d.ts +1 -1
  123. package/dist/types/internal/InputWrapper.d.ts +1 -1
  124. package/dist/types/ranger/index.d.ts +2 -2
  125. package/dist/types/select/AutoComplete.d.ts +8 -1
  126. package/dist/types/select/DualList.d.ts +21 -7
  127. package/dist/types/select/List.d.ts +9 -1
  128. package/dist/types/select/Options.d.ts +4 -3
  129. package/dist/types/select/Select.d.ts +9 -1
  130. package/dist/types/select/useSelect.d.ts +10 -6
  131. package/dist/types/types/index.d.ts +38 -10
  132. package/dist/types/types/schema.d.ts +78 -33
  133. package/dist/types/utils/eventHandlers.d.ts +2 -2
  134. package/package.json +22 -20
  135. package/src/builder/FileField.tsx +56 -30
  136. package/src/builder/FormField.tsx +52 -32
  137. package/src/builder/SchemaEditor.tsx +79 -0
  138. package/src/builder/components/AddSchemaFields.tsx +75 -0
  139. package/src/builder/components/SchemaArrayForm.tsx +155 -0
  140. package/src/builder/components/SchemaField.tsx +435 -0
  141. package/src/form/Controller.tsx +48 -3
  142. package/src/form/Form.tsx +84 -13
  143. package/src/hooks/useFileUploader.ts +16 -0
  144. package/src/hooks/useFormBuilder.tsx +70 -19
  145. package/src/i18n/ar.json +5 -4
  146. package/src/i18n/en.json +5 -5
  147. package/src/index.ts +12 -3
  148. package/src/input/ArrayInput.tsx +195 -66
  149. package/src/input/AvatarInput.tsx +66 -18
  150. package/src/input/Checkbox.tsx +22 -9
  151. package/src/input/ColorInput.tsx +128 -72
  152. package/src/input/ColorPicker.tsx +54 -72
  153. package/src/input/DateInput.tsx +260 -0
  154. package/src/input/Field.tsx +15 -11
  155. package/src/input/File.tsx +18 -16
  156. package/src/input/Hidden.tsx +17 -2
  157. package/src/input/Input.tsx +27 -13
  158. package/src/input/Number.tsx +22 -13
  159. package/src/input/Password.tsx +28 -18
  160. package/src/input/Radio.tsx +15 -6
  161. package/src/input/RadioGroup.tsx +12 -3
  162. package/src/input/{Range.tsx → RangeSlider.tsx} +17 -9
  163. package/src/input/Search.tsx +36 -25
  164. package/src/input/Slider.tsx +20 -11
  165. package/src/input/Switch.tsx +17 -6
  166. package/src/input/Textarea.tsx +34 -9
  167. package/src/internal/ErrorIcon.tsx +3 -3
  168. package/src/internal/FieldWrapper.tsx +8 -4
  169. package/src/internal/InputWrapper.tsx +56 -30
  170. package/src/select/AutoComplete.tsx +16 -6
  171. package/src/select/DualList.tsx +40 -22
  172. package/src/select/List.tsx +52 -8
  173. package/src/select/Options.tsx +50 -46
  174. package/src/select/Select.tsx +29 -10
  175. package/src/select/useSelect.tsx +26 -9
  176. package/src/types/index.ts +42 -10
  177. package/src/types/schema.ts +96 -41
  178. package/src/utils/eventHandlers.ts +14 -4
  179. package/dist/cjs/input/ArrayInput.module.css +0 -1
  180. package/dist/cjs/input/ColorPicker.module.css +0 -1
  181. package/dist/cjs/input/File.module.css +0 -1
  182. package/dist/cjs/internal/Field.module.css +0 -1
  183. package/dist/esm/input/ArrayInput.module.css +0 -1
  184. package/dist/esm/input/ColorPicker.module.css +0 -1
  185. package/dist/esm/input/File.module.css +0 -1
  186. package/dist/esm/internal/Field.module.css +0 -1
  187. package/dist/types/input/Range.d.ts +0 -59
@@ -4,7 +4,7 @@ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
4
4
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
5
5
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
6
6
  import { useDebounce } from '@react-fabric/core';
7
- import { matchString, isString, dedupe, groupBy, isArray, EMPTY_ARRAY } from '@react-fabric/utilities';
7
+ import { matchString, isString, dedupe, compareValues, groupBy, isArray, EMPTY_ARRAY } from '@react-fabric/utilities';
8
8
  import { useMemo, useDeferredValue, useRef, useCallback, useReducer, useEffect } from 'react';
9
9
  import { getSelectedValue, makeOption } from './helpers.js';
10
10
 
@@ -15,6 +15,10 @@ var useSelect = function useSelect(_ref) {
15
15
  options = _ref$options === void 0 ? EMPTY_ARRAY : _ref$options,
16
16
  value = _ref.value,
17
17
  autoComplete = _ref.autoComplete,
18
+ _ref$alwaysOpen = _ref.alwaysOpen,
19
+ alwaysOpen = _ref$alwaysOpen === void 0 ? false : _ref$alwaysOpen,
20
+ _ref$defaultOpen = _ref.defaultOpen,
21
+ defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen,
18
22
  _ref$multiple = _ref.multiple,
19
23
  multiple = _ref$multiple === void 0 ? false : _ref$multiple,
20
24
  _ref$allowCreate = _ref.allowCreate,
@@ -25,6 +29,7 @@ var useSelect = function useSelect(_ref) {
25
29
  valueProperty = _ref$valueProperty === void 0 ? "id" : _ref$valueProperty,
26
30
  _ref$labelProperty = _ref.labelProperty,
27
31
  labelProperty = _ref$labelProperty === void 0 ? "label" : _ref$labelProperty,
32
+ sortProperty = _ref.sortProperty,
28
33
  _ref$createOption = _ref.createOption,
29
34
  createOption = _ref$createOption === void 0 ? makeOption : _ref$createOption,
30
35
  matcher = _ref.matcher,
@@ -63,13 +68,16 @@ var useSelect = function useSelect(_ref) {
63
68
  if (action.type === "close") {
64
69
  return _objectSpread(_objectSpread({}, state), {}, {
65
70
  activeIndex: null,
71
+ activeItem: null,
66
72
  open: false
67
73
  });
68
74
  }
69
75
  if (action.type === "active" && state.open) {
76
+ var _action$index;
70
77
  if (autoComplete && action.index !== null) state.query = state.items[action.index];
71
78
  return _objectSpread(_objectSpread({}, state), {}, {
72
- activeIndex: action.index
79
+ activeIndex: action.index,
80
+ activeItem: state.items[(_action$index = action.index) !== null && _action$index !== void 0 ? _action$index : -1]
73
81
  });
74
82
  }
75
83
  if (action.type === "setValue") {
@@ -83,6 +91,7 @@ var useSelect = function useSelect(_ref) {
83
91
  var newState = _objectSpread(_objectSpread({}, state), {}, {
84
92
  value: state.emptyValue,
85
93
  activeIndex: null,
94
+ activeItem: null,
86
95
  selectedIndex: autoComplete ? state.multiple ? (_action$value = action.value) === null || _action$value === void 0 ? void 0 : _action$value.length : 0 : state.items.indexOf(action.value)
87
96
  });
88
97
  if (action.value !== undefined) {
@@ -100,16 +109,16 @@ var useSelect = function useSelect(_ref) {
100
109
  newState.value = action.value;
101
110
  }
102
111
  }
103
- if (!state.multiple) newState.open = false;
112
+ if (!state.multiple) newState.open = alwaysOpen;
104
113
  fireChange(newState.value);
105
114
  return newState;
106
115
  }
107
116
  if (action.type === "removeItem") {
108
117
  var newValue = state.value;
109
118
  if (state.multiple) {
110
- var _action$index;
119
+ var _action$index2;
111
120
  newValue = _toConsumableArray(newValue);
112
- newValue.splice((_action$index = action.index) !== null && _action$index !== void 0 ? _action$index : -1, 1);
121
+ newValue.splice((_action$index2 = action.index) !== null && _action$index2 !== void 0 ? _action$index2 : -1, 1);
113
122
  } else {
114
123
  newValue = "";
115
124
  }
@@ -133,13 +142,14 @@ var useSelect = function useSelect(_ref) {
133
142
  if (autoComplete && action.query !== undefined) {
134
143
  optionList = dedupe([action.query].concat(_toConsumableArray(optionList)));
135
144
  }
145
+ if (sortProperty) optionList = optionList.sort(compareValues("asc", sortProperty));
136
146
  var grouped = groupBy(optionList, groupProperty, "");
137
147
  if (action.open) _newState.open = true;
138
148
  _newState.items = [];
139
149
  // add new item if allowCreate
140
150
  if (allowCreate && action.query) _newState.items.push({
141
151
  ___create___: true,
142
- value: createOption(action.query)
152
+ value: action.query
143
153
  });
144
154
  Object.entries(grouped).forEach(function (_ref2) {
145
155
  var _newState$items;
@@ -169,9 +179,10 @@ var useSelect = function useSelect(_ref) {
169
179
  }, {
170
180
  multiple: multiple,
171
181
  emptyValue: emptyValue,
172
- open: false,
182
+ open: alwaysOpen || defaultOpen,
173
183
  loading: false,
174
184
  activeIndex: null,
185
+ activeItem: null,
175
186
  selectedIndex: null,
176
187
  value: emptyValue,
177
188
  // filter
@@ -201,7 +212,7 @@ var useSelect = function useSelect(_ref) {
201
212
  });
202
213
  dispatch({
203
214
  type: "setValue",
204
- value: (_ref4 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref4 !== void 0 ? _ref4 : ""
215
+ value: (_ref4 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref4 !== void 0 ? _ref4 : deferred
205
216
  });
206
217
  }
207
218
  if (multiple) {
@@ -211,12 +222,12 @@ var useSelect = function useSelect(_ref) {
211
222
  var newOption = (allowCreate || autoComplete) && item ? createOption(item) : undefined;
212
223
  var hasValue = options.find(function (opt) {
213
224
  var _opt$valueProperty2;
214
- return ((_opt$valueProperty2 = opt[valueProperty]) !== null && _opt$valueProperty2 !== void 0 ? _opt$valueProperty2 : opt) === deferred;
225
+ return ((_opt$valueProperty2 = opt[valueProperty]) !== null && _opt$valueProperty2 !== void 0 ? _opt$valueProperty2 : opt) === item;
215
226
  });
216
227
  if (!hasValue && newOption) {
217
228
  optionsRef.current.push(newOption);
218
229
  }
219
- return (_ref5 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref5 !== void 0 ? _ref5 : "";
230
+ return (_ref5 = hasValue !== null && hasValue !== void 0 ? hasValue : newOption) !== null && _ref5 !== void 0 ? _ref5 : item;
220
231
  });
221
232
  optionsRef.current = [].concat(_toConsumableArray(optionsRef.current), _toConsumableArray(options !== null && options !== void 0 ? options : []));
222
233
  dispatch({
@@ -246,7 +257,7 @@ var useSelect = function useSelect(_ref) {
246
257
  setActive: true
247
258
  });
248
259
  });
249
- }, [onQuery]);
260
+ }, [onQuery], 300);
250
261
 
251
262
  // handlers
252
263
  var handleQuery = useCallback(function (query) {
@@ -316,7 +327,7 @@ var useSelect = function useSelect(_ref) {
316
327
  });
317
328
  }, []);
318
329
  var setActiveIndex = useCallback(function (index) {
319
- dispatch({
330
+ index && index > -1 && dispatch({
320
331
  type: "active",
321
332
  index: index
322
333
  });
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  /*
2
4
  * React Fabric
3
5
  * @version: 1.0.0
@@ -21,31 +23,20 @@
21
23
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
24
  */
23
25
 
24
- @layer comp {
25
- .colorPicker {
26
- --color-shadow: theme(borderColor.base);
27
-
28
- & input {
29
- @apply bg-base text-base !border !border-solid !rounded-sm !border-base focus:!border-primary !shadow-none;
30
-
31
- padding: 0 4px !important;
32
- line-height: 2;
33
- }
34
-
35
- & label {
36
- @apply !text-base;
37
- }
38
-
39
- & :global(.flexbox-fix) {
40
- @apply !border-t-muted justify-center;
41
-
42
- & > div > div {
43
- @apply text-center;
44
- }
26
+ var DATA_TYPES = /*#__PURE__*/function (DATA_TYPES) {
27
+ DATA_TYPES["TEXT"] = "text";
28
+ DATA_TYPES["COLOR"] = "color";
29
+ DATA_TYPES["BOOL"] = "bool";
30
+ DATA_TYPES["DATE"] = "date";
31
+ DATA_TYPES["DATETIME"] = "datetime";
32
+ DATA_TYPES["STRING"] = "string";
33
+ DATA_TYPES["NUMBER"] = "number";
34
+ DATA_TYPES["RANGE"] = "range";
35
+ DATA_TYPES["FILE"] = "file";
36
+ DATA_TYPES["AVATAR"] = "avatar";
37
+ DATA_TYPES["SCHEMA"] = "schema";
38
+ return DATA_TYPES;
39
+ }({});
40
+ var SCHEMA_CUSTOM_LIST = "--CUSTOM--";
45
41
 
46
- & span > div {
47
- box-shadow: 0 0 1px 1px theme(borderColor.base) inset !important;
48
- }
49
- }
50
- }
51
- }
42
+ export { DATA_TYPES, SCHEMA_CUSTOM_LIST };
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { debounce } from '@react-fabric/utilities';
3
+ import { useFloatingTree } from '@floating-ui/react';
4
+ import { useDebounce } from '@react-fabric/core';
4
5
 
5
6
  /*
6
7
  * React Fabric
@@ -26,16 +27,25 @@ import { debounce } from '@react-fabric/utilities';
26
27
  */
27
28
 
28
29
  /** ***************** common handler for enter press *******************/
29
- var handleEnter = function handleEnter(callback) {
30
+ var useHandleEnter = function useHandleEnter(callback) {
30
31
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
31
32
  _ref$stopPropagation = _ref.stopPropagation,
32
33
  stopPropagation = _ref$stopPropagation === void 0 ? false : _ref$stopPropagation,
33
34
  _ref$preventDefault = _ref.preventDefault,
34
35
  preventDefault = _ref$preventDefault === void 0 ? false : _ref$preventDefault;
35
- var cbHandle = debounce(callback !== null && callback !== void 0 ? callback : function () {
36
+ var cbHandle = useDebounce(callback !== null && callback !== void 0 ? callback : function () {
36
37
  return undefined;
37
- }, 100);
38
+ }, [callback], 100);
39
+ var tree = useFloatingTree();
38
40
  return function (e) {
41
+ // prevent propagation of event if input within dropdown (work around for floating-ui typeahead)
42
+ if (tree && e.key !== "Escape") {
43
+ e === null || e === void 0 || e.stopPropagation();
44
+ }
45
+ // blur input on escape key press
46
+ if (e.key === "Escape") {
47
+ e.currentTarget.blur();
48
+ }
39
49
  if (!e.shiftKey && !e.altKey && !e.metaKey && e.key === "Enter" && callback) {
40
50
  if (stopPropagation) e === null || e === void 0 || e.stopPropagation();
41
51
  cbHandle(e);
@@ -47,4 +57,4 @@ var handleEnter = function handleEnter(callback) {
47
57
  };
48
58
  };
49
59
 
50
- export { handleEnter };
60
+ export { useHandleEnter };
@@ -1,8 +1,10 @@
1
1
  import { type UploadHandler } from "../hooks/useFileUploader";
2
- import { type FileSchema } from "../types/schema";
3
- export declare const FileField: ({ uploadHandler, inline, label, accept, multiple, value, ...rest }: Partial<FileSchema> & {
2
+ import { type FileSchema, type ValueType } from "../types/schema";
3
+ export declare const FileField: ({ uploadHandler, inline, label, accept, value, fileUrl, multiple, invalid, error, ...rest }: Partial<FileSchema & ValueType> & {
4
4
  value?: AnyObject;
5
5
  inline?: boolean;
6
+ invalid?: boolean;
7
+ error?: AnyObject;
6
8
  fileUrl?: (path: string) => string;
7
9
  uploadHandler: UploadHandler;
8
10
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,11 @@
1
1
  import { type UploadHandler } from "../hooks/useFileUploader";
2
+ import { type BaseSelectProps } from "../types";
2
3
  import { type SchemaType } from "../types/schema";
3
- export declare const FormField: ({ id, label, required, inline, prefix, autoFocus, defaultValue, fileUrl, uploadHandler, ...rest }: SchemaType & {
4
+ export declare const FormField: ({ id, label, required, inline, prefix, autoFocus, optionLists, fileUrl, uploadHandler, ...rest }: SchemaType & {
4
5
  inline?: boolean;
5
6
  prefix?: string;
6
7
  autoFocus?: boolean;
8
+ optionLists?: KeyValue<BaseSelectProps<any>>;
7
9
  fileUrl?: (path: string) => string;
8
10
  uploadHandler?: UploadHandler;
9
11
  }) => import("react/jsx-runtime").JSX.Element | undefined;
@@ -0,0 +1,9 @@
1
+ import { type SchemaEditorProps } from "../types/schema";
2
+ /**
3
+ * SchemaEditor component allows users to edit a schema definition.
4
+ * It provides a form interface to modify schema properties dynamically.
5
+ *
6
+ * @param {SchemaEditorProps} props - The properties for the SchemaEditor component.
7
+ * @returns {JSX.Element} The rendered SchemaEditor component.
8
+ */
9
+ export declare const SchemaEditor: ({ schemaDef, dynamic, acceptableTypes, optionLists, children, onSubmit, onChange, }: SchemaEditorProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { type ModalProps } from "@react-fabric/core";
2
+ export declare const AddSchemaFields: (props: ModalProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { type SchemaEditorProps } from "../../types/schema";
2
+ export declare const SchemaArrayForm: ({ dynamic, acceptableTypes, optionLists, }: Partial<SchemaEditorProps>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { type SchemaEditorProps } from "../../types/schema";
2
+ export declare const SchemaField: ({ id, field, fieldId, getModel, onRemove, defaultOpen, optionLists, dynamic, onTypeChange, acceptableTypes, }: {
3
+ id: string;
4
+ field: string;
5
+ fieldId: string;
6
+ defaultOpen?: boolean;
7
+ onRemove: () => void;
8
+ getModel: () => KeyValue;
9
+ onTypeChange: (val: KeyValue) => void;
10
+ } & Omit<SchemaEditorProps, "schemaDef" | "onChange">) => import("react/jsx-runtime").JSX.Element;
@@ -4,7 +4,7 @@ export interface ControllerProps {
4
4
  * field name
5
5
  */
6
6
  name?: string;
7
- children: ReactElement | ((props: {
7
+ children: ReactElement<KeyValue> | ((props: {
8
8
  name: string;
9
9
  error?: string;
10
10
  checked: boolean;
@@ -14,7 +14,52 @@ export interface ControllerProps {
14
14
  disabled?: boolean;
15
15
  onBlur: () => void;
16
16
  onChange: (value: AnyObject) => void;
17
- inputRef?: React.Ref<HTMLInputElement>;
17
+ ref?: React.Ref<HTMLInputElement>;
18
18
  }) => ReactElement);
19
19
  }
20
+ /**
21
+ * This component is used to wrap form controls
22
+ * and provide them with the necessary props and state management.
23
+ *
24
+ * It uses the `Controller` component from `react-hook-form`
25
+ * to manage the form state and validation.
26
+ *
27
+ * It accepts a `name` prop to identify the form control,
28
+ * and a `children` prop which can either be a React element
29
+ * or a function that receives the necessary props to render the control.
30
+ *
31
+ * The component will pass down the following props to the child:
32
+ * - `name`: the name of the form control
33
+ * - `error`: any validation error message
34
+ * - `checked`: whether the control is checked (for checkboxes/radios)
35
+ * - `value`: the current value of the control
36
+ * - `invalid`: whether the control is invalid
37
+ * - `readOnly`: whether the control is read-only (disabled during submission)
38
+ * - `disabled`: whether the control is disabled
39
+ * - `onBlur`: function to call when the control loses focus
40
+ * - `onChange`: function to call when the control value changes
41
+ * - `ref`: a ref to the control element
42
+ * * The component also handles the `ref` prop to ensure that it is passed correctly
43
+ * to the child component, allowing for proper focus management and DOM access.
44
+ *
45
+ * @param {ControllerProps} props - The properties for the Controller component.
46
+ * @returns {JSX.Element} The rendered Controller component.
47
+ *
48
+ * @example
49
+ * ```jsx
50
+ * <Controller
51
+ * name="username"
52
+ * children={({ name, error, checked, value, invalid, readOnly, onChange }) => (
53
+ * <input
54
+ * type="text"
55
+ * name={name}
56
+ * onChange={onChange}
57
+ * readOnly={readOnly}
58
+ * aria-invalid={invalid}
59
+ * value={value}
60
+ * />
61
+ * )}
62
+ * />
63
+ * ```
64
+ */
20
65
  export declare const Controller: ({ name, children, ...rest }: ControllerProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,8 @@
1
- import { type yup } from "@react-fabric/utilities";
2
1
  import { type PropsWithChildren, type Ref } from "react";
3
- import { type FormState } from "react-hook-form";
2
+ import { type FormState, type Resolver } from "react-hook-form";
3
+ type NestedKeyOf<T extends object> = {
4
+ [K in keyof T & (string | number)]: T[K] extends object ? `${K}` | `${K}.${NestedKeyOf<T[K]>}` : K;
5
+ }[keyof T & (string | number)];
4
6
  export interface FormRef<K extends KeyValue> {
5
7
  state: FormState<K>;
6
8
  reset: () => void;
@@ -8,15 +10,16 @@ export interface FormRef<K extends KeyValue> {
8
10
  submit: () => void;
9
11
  validate: () => Promise<boolean>;
10
12
  getValues: () => K;
11
- setValue: (key: keyof K, value: AnyObject) => void;
13
+ setValue: (key: NestedKeyOf<K>, value: AnyObject) => void;
12
14
  setValues: (values: K) => void;
13
15
  }
14
16
  export interface FormProps<K extends KeyValue = KeyValue> {
15
17
  formRef?: Ref<FormRef<K>>;
16
18
  /**
17
- * form data schema
19
+ * react-hook-form resolver for validation
20
+ * @see {@link https://react-hook-form.com/ts#Resolver}
18
21
  */
19
- schema?: yup.ObjectSchema<K>;
22
+ resolver?: Resolver<K>;
20
23
  /**
21
24
  * default data values
22
25
  */
@@ -30,4 +33,44 @@ export interface FormProps<K extends KeyValue = KeyValue> {
30
33
  */
31
34
  onSubmit?: (values: K) => void;
32
35
  }
33
- export declare const Form: <K extends KeyValue<any>>({ formRef, schema, children, defaultValues, onSubmit, onChange, ...rest }: PropsWithChildren<FormProps<K>>) => import("react/jsx-runtime").JSX.Element;
36
+ /**
37
+ * Form component for managing form state and validation using react-hook-form and yup.
38
+ * It provides a simple interface for form handling, including submission, validation, and value management.
39
+ * It supports nested form structures and allows for custom validation schemas using Yup.
40
+ *
41
+ * @param {FormProps<K>} props - The properties for the Form component.
42
+ * @returns {JSX.Element} The rendered Form component.
43
+ *
44
+ * @example
45
+ * ```jsx
46
+ * <Form
47
+ * formRef={formRef}
48
+ * resolver={hookformResolver(schema)}
49
+ * defaultValues={{ name: "", email: "" }}
50
+ * onSubmit={(values) => {
51
+ * console.log("Form submitted with values:", values);
52
+ * }}
53
+ * >
54
+ * <input name="name" ref={form.register} placeholder="Name" />
55
+ * <input name="email" ref={form.register} placeholder="Email" />
56
+ * <button type="submit">Submit</button>
57
+ * </Form>
58
+ * ```
59
+ *
60
+ * @see {@link https://adarshpastakia.github.io/react-fabric/?path=/docs/form-form--docs} for the properties that can be passed to this component.
61
+ * @see {@link https://react-hook-form.com/docs/useform} for more details on the properties.
62
+ * @see {@link https://github.com/jquense/yup} for more details on the Yup validation schema.
63
+ */
64
+ export declare const Form: <K extends KeyValue>({ formRef, resolver, children, defaultValues, onSubmit, onChange, ...rest }: PropsWithChildren<FormProps<K>>) => import("react/jsx-runtime").JSX.Element;
65
+ export declare const useForm: <K extends KeyValue = KeyValue>() => {
66
+ values: import("react-hook-form").DeepPartialSkipArrayKey<K> & K;
67
+ formState: FormState<K>;
68
+ getValues: import("react-hook-form").UseFormGetValues<K>;
69
+ setValue: import("react-hook-form").UseFormSetValue<K>;
70
+ watch: import("react-hook-form").UseFormWatch<K>;
71
+ reset: import("react-hook-form").UseFormReset<K>;
72
+ resetField: import("react-hook-form").UseFormResetField<K>;
73
+ setError: import("react-hook-form").UseFormSetError<K>;
74
+ setFocus: import("react-hook-form").UseFormSetFocus<K>;
75
+ };
76
+ export {};
@@ -12,6 +12,22 @@ interface FileInfo {
12
12
  progress?: number;
13
13
  abort?: AbortController["abort"];
14
14
  }
15
+ /**
16
+ * useFileUploader hook provides a way to handle file uploads
17
+ * with progress tracking, error handling, and file management.
18
+ * It uses a reducer to manage the state of uploaded files and their statuses.
19
+ *
20
+ * @param uploader - The function that handles the file upload.
21
+ * @param initialList - Initial list of files to be managed by the uploader.
22
+ * @param multiple - Whether to allow multiple file uploads or not.
23
+ * @returns An object containing methods to upload, remove, retry files,
24
+ * and the current state of the uploader including pending uploads and file list.
25
+ *
26
+ * @example
27
+ * ```jsx
28
+ * const { upload, remove, retry, state } = useFileUploader(uploader, initialList, multiple);
29
+ * ```
30
+ */
15
31
  export declare const useFileUploader: (uploader: UploadHandler, initialList?: string | FileInfo | FileInfo[], multiple?: boolean) => {
16
32
  upload: (files: FileList | null) => void;
17
33
  remove: (key: string) => void;
@@ -1,13 +1,50 @@
1
1
  import { yup } from "@react-fabric/utilities";
2
+ import { type BaseSelectProps } from "../types";
2
3
  import { type FormSchema } from "../types/schema";
3
4
  import { type UploadHandler } from "./useFileUploader";
4
- export declare const useFormBuilder: (schema: FormSchema[], options?: {
5
+ /**
6
+ * useFormBuilder hook to create a form definition based on a schema.
7
+ * It generates a Yup validation schema and a form definition component.
8
+ *
9
+ * @param {FormSchema} schema - The schema defining the form fields.
10
+ * @param {Object} options - Optional parameters for the form builder.
11
+ * @returns An object containing the form definition and the Yup validation schema.
12
+ *
13
+ * @example
14
+ * ```jsx
15
+ * const { formDef, schemaDef } = useFormBuilder(schema, {
16
+ * prefix: "form",
17
+ * inline: true,
18
+ * fileUrl: (path) => `/files/${path}`,
19
+ * uploadHandler: async (file) => {
20
+ * // handle file upload
21
+ * },
22
+ * optionLists: {
23
+ * // define option lists for select fields
24
+ * }
25
+ * * });
26
+ * <FormBuilder
27
+ * schema={schemaDef}
28
+ * onSubmit={(data) => console.log(data)}
29
+ * >
30
+ * {formDef}
31
+ * </FormBuilder>
32
+ * ```
33
+ */
34
+ export declare const useFormBuilder: <T extends AnyObject = string>(schema: FormSchema, options?: {
5
35
  prefix?: string;
6
36
  inline?: boolean;
7
37
  fileUrl?: (path: string) => string;
8
38
  uploadHandler?: UploadHandler;
39
+ optionLists?: KeyValue<BaseSelectProps<T>>;
9
40
  }) => {
10
41
  formDef: import("react/jsx-runtime").JSX.Element;
42
+ resolver: import("react-hook-form").Resolver<{
43
+ [x: string]: any;
44
+ }, unknown, {
45
+ [x: string]: any;
46
+ [x: number]: any;
47
+ }>;
11
48
  schemaDef: yup.ObjectSchema<{
12
49
  [x: string]: any;
13
50
  }, yup.AnyObject, {
@@ -1,13 +1,16 @@
1
1
  import "./i18n";
2
2
  export { Controller } from "./form/Controller";
3
- export { Form, type FormRef } from "./form/Form";
3
+ export { Form, useForm, type FormRef } from "./form/Form";
4
+ export { SchemaEditor } from "./builder/SchemaEditor";
4
5
  export { useFileUploader } from "./hooks/useFileUploader";
5
6
  export { useFormBuilder } from "./hooks/useFormBuilder";
6
- export { type FormSchema } from "./types/schema";
7
+ export { DATA_TYPES, SCHEMA_CUSTOM_LIST, type FormSchema, type SchemaDef, } from "./types/schema";
7
8
  export { ArrayInput } from "./input/ArrayInput";
9
+ export { AvatarInput } from "./input/AvatarInput";
8
10
  export { Checkbox } from "./input/Checkbox";
9
11
  export { ColorInput } from "./input/ColorInput";
10
12
  export { ColorPicker } from "./input/ColorPicker";
13
+ export { DateInput } from "./input/DateInput";
11
14
  export { Field } from "./input/Field";
12
15
  export { FileInput } from "./input/File";
13
16
  export { HiddenInput } from "./input/Hidden";
@@ -16,7 +19,7 @@ export { Number } from "./input/Number";
16
19
  export { Password } from "./input/Password";
17
20
  export { Radio } from "./input/Radio";
18
21
  export { RadioGroup } from "./input/RadioGroup";
19
- export { Range } from "./input/Range";
22
+ export { RangeSlider } from "./input/RangeSlider";
20
23
  export { Search } from "./input/Search";
21
24
  export { Slider } from "./input/Slider";
22
25
  export { Switch } from "./input/Switch";
@@ -1,5 +1,5 @@
1
- import { type ReactNode, type RefObject } from "react";
2
- export interface ArrayInputProps {
1
+ import { type Ref } from "react";
2
+ export interface ArrayInputProps<T extends AnyObject = string> {
3
3
  /**
4
4
  * input label
5
5
  */
@@ -32,6 +32,10 @@ export interface ArrayInputProps {
32
32
  * minimum required length
33
33
  */
34
34
  minItems?: number;
35
+ /**
36
+ * maximum length
37
+ */
38
+ maxItems?: number;
35
39
  /**
36
40
  * field name to focus on add
37
41
  */
@@ -43,23 +47,37 @@ export interface ArrayInputProps {
43
47
  children: React.ReactNode | ((props: {
44
48
  index: number;
45
49
  name: string;
46
- }) => ReactNode);
50
+ item: T;
51
+ }) => React.ReactNode);
47
52
  /**
48
53
  * add item button label
49
54
  */
50
55
  addLabel?: string;
51
- /**
52
- * fixed length list
53
- */
54
- fixedList?: boolean;
55
- arrayRef?: RefObject<{
56
- addItem: (item: AnyObject) => void;
56
+ buttonPosition?: "top" | "bottom" | "both";
57
+ arrayRef?: Ref<{
58
+ addItem: (item: T) => void;
57
59
  removeItem: (idx: number) => void;
58
60
  }>;
59
61
  /**
60
- * Add item
62
+ * add new item
63
+ */
64
+ onAdd?: () => T;
65
+ /**
66
+ * on item remove
61
67
  */
62
- onAdd?: () => AnyObject;
68
+ onRemove?: (item: T, idx: number) => void;
69
+ /**
70
+ * before item remove
71
+ */
72
+ onBeforeRemove?: (item: T, idx: number) => Promise<boolean> | boolean;
73
+ /**
74
+ * can remove item
75
+ */
76
+ canRemove?: false | "newonly" | ((props: {
77
+ item: T;
78
+ index: number;
79
+ lastItem: boolean;
80
+ }) => boolean);
63
81
  /**
64
82
  * field width
65
83
  */
@@ -73,4 +91,43 @@ export interface ArrayInputProps {
73
91
  */
74
92
  labelWidth?: string;
75
93
  }
76
- export declare const ArrayInput: ({ name, children, addLabel, fixedList, focusName, onAdd, arrayRef, enableSorting, disabled, readOnly, minItems, ...rest }: ArrayInputProps) => import("react/jsx-runtime").JSX.Element;
94
+ /**
95
+ * ArrayInput component for managing an array of items in a form.
96
+ * It allows adding, removing, and sorting items within the array.
97
+ * It integrates with react-hook-form for form state management and validation.
98
+ * It supports fixed-length lists, custom add/remove handlers, and can display validation errors.
99
+ * It also provides options for inline display and custom button positioning.
100
+ *
101
+ * It uses the `useFieldArray` hook from `react-hook-form` to manage the array state and provides a simple interface for adding and removing items.
102
+ *
103
+ * It also supports drag-and-drop sorting using `@dnd-kit/core` and `@dnd-kit/sortable` for a better user experience when reordering items.
104
+ *
105
+ * @param {ArrayInputProps<T>} props - The properties for the ArrayInput component.
106
+ * @returns {JSX.Element} The rendered ArrayInput component.
107
+ *
108
+ * @example
109
+ * ```jsx
110
+ * <ArrayInput
111
+ * name="items"
112
+ * label="Items"
113
+ * addLabel="Add Item"
114
+ * onAdd={() => ({ name: "", value: "" })}
115
+ * onRemove={(item, index) => console.log("Removed item:", item, "at index:", index)}
116
+ * onBeforeRemove={(item, index) => confirm(`Are you sure you want to remove item at index ${index}?`)}
117
+ * canRemove={({ item, index, lastItem }) => !lastItem} // Prevent removing the last item
118
+ * >
119
+ * {({ index, name }) => (
120
+ * <Input
121
+ * name={name}
122
+ * label={`Item ${index + 1}`}
123
+ * placeholder="Enter item value"
124
+ * required={index === 0} // Make the first item required
125
+ * />
126
+ * )}
127
+ * </ArrayInput>
128
+ * ```
129
+ *
130
+ * @see {@link https://react-hook-form.com/api/usefieldarray} for more details on `useFieldArray`.
131
+ * @see {@link https://react-dnd.github.io/react-dnd/about} for more details on DnD context and sorting.
132
+ */
133
+ export declare const ArrayInput: <T extends AnyObject = string>({ name, children, addLabel, focusName, buttonPosition, onAdd, onRemove, onBeforeRemove, canRemove, arrayRef, enableSorting, disabled, readOnly, minItems, maxItems, ...rest }: ArrayInputProps<T>) => import("react/jsx-runtime").JSX.Element;