@react-fabric/form 1.0.0-beta.4 → 1.0.0-beta.41

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 (155) 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} +26 -15
  4. package/{src/input/File.module.css → css/_file.css} +20 -6
  5. package/css/styles.css +27 -0
  6. package/dist/cjs/builder/FileField.js +37 -25
  7. package/dist/cjs/builder/FormField.js +44 -34
  8. package/dist/cjs/builder/SchemaEditor.js +72 -0
  9. package/dist/cjs/builder/components/AddSchemaFields.js +62 -0
  10. package/dist/cjs/builder/components/SchemaArrayForm.js +143 -0
  11. package/dist/cjs/builder/components/SchemaField.js +413 -0
  12. package/dist/cjs/form/Controller.js +1 -1
  13. package/dist/cjs/form/Form.js +19 -10
  14. package/dist/cjs/hooks/useFormBuilder.js +27 -15
  15. package/dist/cjs/index.js +9 -2
  16. package/dist/cjs/input/ArrayInput.js +36 -25
  17. package/dist/cjs/input/AvatarInput.js +1 -1
  18. package/dist/cjs/input/Checkbox.js +5 -4
  19. package/dist/cjs/input/ColorInput.js +70 -28
  20. package/dist/cjs/input/ColorPicker.js +1 -35
  21. package/dist/cjs/input/DateInput.js +183 -0
  22. package/dist/cjs/input/Field.js +4 -4
  23. package/dist/cjs/input/File.js +2 -3
  24. package/dist/cjs/input/Hidden.js +3 -1
  25. package/dist/cjs/input/Input.js +1 -1
  26. package/dist/cjs/input/Number.js +1 -1
  27. package/dist/cjs/input/Password.js +1 -1
  28. package/dist/cjs/input/Radio.js +1 -1
  29. package/dist/cjs/input/RadioGroup.js +6 -3
  30. package/dist/cjs/input/{Range.js → RangeSlider.js} +3 -3
  31. package/dist/cjs/input/Search.js +1 -1
  32. package/dist/cjs/input/Slider.js +1 -1
  33. package/dist/cjs/input/Switch.js +27 -5
  34. package/dist/cjs/input/Textarea.js +7 -3
  35. package/dist/cjs/internal/ErrorIcon.js +1 -1
  36. package/dist/cjs/internal/FieldWrapper.js +4 -3
  37. package/dist/cjs/internal/InputWrapper.js +14 -16
  38. package/dist/cjs/select/AutoComplete.js +9 -6
  39. package/dist/cjs/select/List.js +41 -20
  40. package/dist/cjs/select/Options.js +2 -2
  41. package/dist/cjs/select/Select.js +15 -9
  42. package/dist/cjs/select/useSelect.js +15 -8
  43. package/{src/input/ColorPicker.module.css → dist/cjs/types/schema.js} +18 -27
  44. package/dist/cjs/utils/getColor.js +6 -0
  45. package/dist/esm/builder/FileField.js +39 -27
  46. package/dist/esm/builder/FormField.js +44 -34
  47. package/dist/esm/builder/SchemaEditor.js +72 -0
  48. package/dist/esm/builder/components/AddSchemaFields.js +62 -0
  49. package/dist/esm/builder/components/SchemaArrayForm.js +143 -0
  50. package/dist/esm/builder/components/SchemaField.js +413 -0
  51. package/dist/esm/form/Controller.js +1 -1
  52. package/dist/esm/form/Form.js +19 -10
  53. package/dist/esm/hooks/useFormBuilder.js +25 -13
  54. package/dist/esm/index.js +4 -1
  55. package/dist/esm/input/ArrayInput.js +38 -27
  56. package/dist/esm/input/AvatarInput.js +1 -1
  57. package/dist/esm/input/Checkbox.js +5 -4
  58. package/dist/esm/input/ColorInput.js +72 -30
  59. package/dist/esm/input/ColorPicker.js +1 -35
  60. package/dist/esm/input/DateInput.js +183 -0
  61. package/dist/esm/input/Field.js +5 -5
  62. package/dist/esm/input/File.js +2 -3
  63. package/dist/esm/input/Hidden.js +3 -1
  64. package/dist/esm/input/Input.js +1 -1
  65. package/dist/esm/input/Number.js +1 -1
  66. package/dist/esm/input/Password.js +1 -1
  67. package/dist/esm/input/Radio.js +1 -1
  68. package/dist/esm/input/RadioGroup.js +7 -4
  69. package/dist/esm/input/{Range.js → RangeSlider.js} +3 -3
  70. package/dist/esm/input/Search.js +1 -1
  71. package/dist/esm/input/Slider.js +1 -1
  72. package/dist/esm/input/Switch.js +29 -7
  73. package/dist/esm/input/Textarea.js +7 -3
  74. package/dist/esm/internal/ErrorIcon.js +1 -1
  75. package/dist/esm/internal/FieldWrapper.js +4 -3
  76. package/dist/esm/internal/InputWrapper.js +14 -16
  77. package/dist/esm/select/AutoComplete.js +9 -6
  78. package/dist/esm/select/List.js +42 -21
  79. package/dist/esm/select/Options.js +2 -2
  80. package/dist/esm/select/Select.js +15 -9
  81. package/dist/esm/select/useSelect.js +16 -9
  82. package/dist/esm/types/schema.js +41 -0
  83. package/dist/esm/utils/getColor.js +6 -1
  84. package/dist/types/builder/FileField.d.ts +4 -2
  85. package/dist/types/builder/FormField.d.ts +3 -1
  86. package/dist/types/builder/SchemaEditor.d.ts +2 -0
  87. package/dist/types/builder/components/AddSchemaFields.d.ts +2 -0
  88. package/dist/types/builder/components/SchemaArrayForm.d.ts +2 -0
  89. package/dist/types/builder/components/SchemaField.d.ts +10 -0
  90. package/dist/types/form/Controller.d.ts +1 -1
  91. package/dist/types/hooks/useFormBuilder.d.ts +3 -1
  92. package/dist/types/index.d.ts +4 -2
  93. package/dist/types/input/ArrayInput.d.ts +20 -3
  94. package/dist/types/input/Checkbox.d.ts +4 -3
  95. package/dist/types/input/ColorInput.d.ts +1 -1
  96. package/dist/types/input/DateInput.d.ts +19 -0
  97. package/dist/types/input/RadioGroup.d.ts +18 -2
  98. package/dist/types/input/{Range.d.ts → RangeSlider.d.ts} +1 -1
  99. package/dist/types/input/Switch.d.ts +7 -3
  100. package/dist/types/input/Textarea.d.ts +5 -1
  101. package/dist/types/internal/InputWrapper.d.ts +1 -1
  102. package/dist/types/select/AutoComplete.d.ts +1 -1
  103. package/dist/types/select/List.d.ts +1 -1
  104. package/dist/types/select/Select.d.ts +1 -1
  105. package/dist/types/select/useSelect.d.ts +2 -1
  106. package/dist/types/types/index.d.ts +17 -5
  107. package/dist/types/types/schema.d.ts +79 -33
  108. package/package.json +10 -7
  109. package/src/builder/FileField.tsx +53 -27
  110. package/src/builder/FormField.tsx +45 -32
  111. package/src/builder/SchemaEditor.tsx +72 -0
  112. package/src/builder/components/AddSchemaFields.tsx +74 -0
  113. package/src/builder/components/SchemaArrayForm.tsx +158 -0
  114. package/src/builder/components/SchemaField.tsx +435 -0
  115. package/src/form/Controller.tsx +2 -2
  116. package/src/form/Form.tsx +15 -8
  117. package/src/hooks/useFormBuilder.tsx +29 -15
  118. package/src/index.ts +10 -2
  119. package/src/input/ArrayInput.tsx +80 -42
  120. package/src/input/AvatarInput.tsx +1 -1
  121. package/src/input/Checkbox.tsx +5 -4
  122. package/src/input/ColorInput.tsx +102 -34
  123. package/src/input/ColorPicker.tsx +1 -35
  124. package/src/input/DateInput.tsx +248 -0
  125. package/src/input/Field.tsx +9 -11
  126. package/src/input/File.tsx +3 -6
  127. package/src/input/Hidden.tsx +4 -1
  128. package/src/input/Input.tsx +2 -2
  129. package/src/input/Number.tsx +2 -2
  130. package/src/input/Password.tsx +2 -2
  131. package/src/input/Radio.tsx +1 -1
  132. package/src/input/RadioGroup.tsx +27 -4
  133. package/src/input/{Range.tsx → RangeSlider.tsx} +2 -2
  134. package/src/input/Search.tsx +2 -2
  135. package/src/input/Slider.tsx +1 -1
  136. package/src/input/Switch.tsx +42 -6
  137. package/src/input/Textarea.tsx +11 -3
  138. package/src/internal/ErrorIcon.tsx +1 -1
  139. package/src/internal/FieldWrapper.tsx +3 -3
  140. package/src/internal/InputWrapper.tsx +21 -20
  141. package/src/select/AutoComplete.tsx +4 -1
  142. package/src/select/List.tsx +37 -8
  143. package/src/select/Options.tsx +1 -1
  144. package/src/select/Select.tsx +9 -3
  145. package/src/select/useSelect.tsx +30 -19
  146. package/src/types/index.ts +22 -7
  147. package/src/types/schema.ts +96 -41
  148. package/dist/cjs/input/ArrayInput.module.css +0 -1
  149. package/dist/cjs/input/ColorPicker.module.css +0 -1
  150. package/dist/cjs/input/File.module.css +0 -1
  151. package/dist/cjs/internal/Field.module.css +0 -1
  152. package/dist/esm/input/ArrayInput.module.css +0 -1
  153. package/dist/esm/input/ColorPicker.module.css +0 -1
  154. package/dist/esm/input/File.module.css +0 -1
  155. package/dist/esm/internal/Field.module.css +0 -1
@@ -0,0 +1,413 @@
1
+ 'use client';
2
+
3
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
4
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
5
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
6
+ import { useSortable } from '@dnd-kit/sortable';
7
+ import { CSS } from '@dnd-kit/utilities';
8
+ import { useOverlayService, Modal, Content, Footer, Button, Collapsable, CoreIcons, ToggleButtonGroup } from '@react-fabric/core';
9
+ import { EMPTY_ARRAY } from '@react-fabric/utilities';
10
+ import classNames from 'classnames';
11
+ import { useState, useCallback, useEffect, Fragment } from 'react';
12
+ import { Controller } from '../../form/Controller.js';
13
+ import { ArrayInput } from '../../input/ArrayInput.js';
14
+ import { Checkbox } from '../../input/Checkbox.js';
15
+ import { DateInput } from '../../input/DateInput.js';
16
+ import { Field } from '../../input/Field.js';
17
+ import { HiddenInput } from '../../input/Hidden.js';
18
+ import { Input } from '../../input/Input.js';
19
+ import { Number } from '../../input/Number.js';
20
+ import { Select } from '../../select/Select.js';
21
+ import { SCHEMA_CUSTOM_LIST, DATA_TYPES } from '../../types/schema.js';
22
+ import { jsxs, jsx } from 'react/jsx-runtime';
23
+
24
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
25
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
26
+ var SchemaField = function SchemaField(_ref) {
27
+ var id = _ref.id,
28
+ field = _ref.field,
29
+ fieldId = _ref.fieldId,
30
+ getModel = _ref.getModel,
31
+ onRemove = _ref.onRemove,
32
+ _ref$defaultOpen = _ref.defaultOpen,
33
+ defaultOpen = _ref$defaultOpen === void 0 ? true : _ref$defaultOpen,
34
+ _ref$optionLists = _ref.optionLists,
35
+ optionLists = _ref$optionLists === void 0 ? EMPTY_ARRAY : _ref$optionLists,
36
+ dynamic = _ref.dynamic,
37
+ onTypeChange = _ref.onTypeChange,
38
+ acceptableTypes = _ref.acceptableTypes;
39
+ var _useState = useState(),
40
+ _useState2 = _slicedToArray(_useState, 2),
41
+ type = _useState2[0],
42
+ setType = _useState2[1];
43
+ var _useState3 = useState(false),
44
+ _useState4 = _slicedToArray(_useState3, 2),
45
+ multiple = _useState4[0],
46
+ setMultiple = _useState4[1];
47
+ var _useState5 = useState(false),
48
+ _useState6 = _slicedToArray(_useState5, 2),
49
+ hasOptions = _useState6[0],
50
+ setHasOptions = _useState6[1];
51
+ var _useState7 = useState(false),
52
+ _useState8 = _slicedToArray(_useState7, 2),
53
+ customOptions = _useState8[0],
54
+ setCustomOptions = _useState8[1];
55
+ var SortableItem = useCallback(function (_ref2) {
56
+ var id = _ref2.id,
57
+ children = _ref2.children,
58
+ className = _ref2.className;
59
+ if (dynamic) {
60
+ var _useSortable = useSortable({
61
+ id: id
62
+ }),
63
+ attributes = _useSortable.attributes,
64
+ listeners = _useSortable.listeners,
65
+ setNodeRef = _useSortable.setNodeRef,
66
+ transform = _useSortable.transform,
67
+ transition = _useSortable.transition,
68
+ isDragging = _useSortable.isDragging;
69
+ return /*#__PURE__*/jsxs("div", {
70
+ className: className,
71
+ ref: setNodeRef,
72
+ style: {
73
+ transform: CSS.Transform.toString(transform),
74
+ transition: transition
75
+ },
76
+ children: [/*#__PURE__*/jsx("div", _objectSpread(_objectSpread(_objectSpread({
77
+ className: classNames("invisible group-hover/field:visible my-2 w-4", isDragging ? "cursor-grabbing" : "cursor-grab")
78
+ }, attributes), listeners), {}, {
79
+ style: {
80
+ backgroundImage: "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='4' width='4'%3E%3Ccircle cx='2' cy='2' r='1' fill='%238888' /%3E%3C/svg%3E \")"
81
+ }
82
+ })), children]
83
+ });
84
+ }
85
+ return /*#__PURE__*/jsx("div", {
86
+ className: className,
87
+ children: children
88
+ });
89
+ }, [dynamic]);
90
+ // @ts-expect-error ignore
91
+ SortableItem.displayName = "SortableItem";
92
+ var _useOverlayService = useOverlayService(function (props) {
93
+ return /*#__PURE__*/jsxs(Modal, _objectSpread(_objectSpread({}, props), {}, {
94
+ children: [/*#__PURE__*/jsx(Content, {
95
+ children: /*#__PURE__*/jsx(ArrayInput, {
96
+ name: "".concat(field, ".options"),
97
+ onAdd: function onAdd() {
98
+ return String("");
99
+ },
100
+ children: /*#__PURE__*/jsx(Controller, {
101
+ children: /*#__PURE__*/jsx(Input, {})
102
+ })
103
+ })
104
+ }), /*#__PURE__*/jsx(Footer, {
105
+ flex: true,
106
+ justify: "end",
107
+ className: "sticky bottom-0 border-t bg-base px-6 py-2",
108
+ children: /*#__PURE__*/jsx(Button, {
109
+ variant: "link",
110
+ onClick: props.onClose,
111
+ children: "Close"
112
+ })
113
+ })]
114
+ }));
115
+ }),
116
+ _useOverlayService2 = _slicedToArray(_useOverlayService, 2),
117
+ OptionModal = _useOverlayService2[0],
118
+ openOptionModal = _useOverlayService2[1];
119
+ useEffect(function () {
120
+ setTimeout(function () {
121
+ var model = getModel();
122
+ setType(model.datatype);
123
+ setMultiple(model.multiple);
124
+ setHasOptions(!!model.optionList);
125
+ setCustomOptions(model.optionList === SCHEMA_CUSTOM_LIST);
126
+ }, 10);
127
+ }, []);
128
+ var handleTypeChange = useCallback(function (type) {
129
+ if (type) {
130
+ var modelRef = getModel();
131
+ var reset = {
132
+ datatype: type,
133
+ id: id,
134
+ label: modelRef.label,
135
+ defaultValue: modelRef.defaultValue,
136
+ required: modelRef.required,
137
+ multiple: type === DATA_TYPES.AVATAR ? false : modelRef.multiple,
138
+ minItems: modelRef.minItems,
139
+ maxItems: modelRef.maxItems
140
+ };
141
+ if (type === DATA_TYPES.STRING) {
142
+ reset = Object.assign(reset, {
143
+ optionList: modelRef.optionList,
144
+ options: modelRef.options,
145
+ regex: modelRef.regex
146
+ });
147
+ } else if (type === DATA_TYPES.DATE) {
148
+ reset = Object.assign(reset, {
149
+ type: "date"
150
+ });
151
+ } else if (type === DATA_TYPES.NUMBER || type === DATA_TYPES.RANGE) {
152
+ reset = Object.assign(reset, {
153
+ min: modelRef.min,
154
+ max: modelRef.max,
155
+ step: modelRef.step
156
+ });
157
+ }
158
+ if (type === DATA_TYPES.AVATAR) {
159
+ setMultiple(false);
160
+ }
161
+ onTypeChange(reset);
162
+ setType(type);
163
+ }
164
+ }, [id]);
165
+ return /*#__PURE__*/jsx(SortableItem, {
166
+ id: fieldId,
167
+ className: "flex flex-nowrap gap-1 group/field",
168
+ children: /*#__PURE__*/jsxs(Collapsable, {
169
+ open: defaultOpen,
170
+ className: "flex-1",
171
+ children: [/*#__PURE__*/jsxs("div", {
172
+ className: "flex flex-nowrap items-center",
173
+ children: [/*#__PURE__*/jsx("span", {
174
+ className: "flex-1 truncate",
175
+ children: id
176
+ }), dynamic && /*#__PURE__*/jsx(Button, {
177
+ size: "sm",
178
+ color: "danger",
179
+ variant: "link",
180
+ "aria-label": "Delete",
181
+ stopPropagation: true,
182
+ icon: CoreIcons.trash,
183
+ onClick: onRemove,
184
+ className: "invisible group-hover/field:visible"
185
+ })]
186
+ }), /*#__PURE__*/jsxs("div", {
187
+ className: "flex flex-col gap-1 pb-4",
188
+ children: [/*#__PURE__*/jsx(Controller, {
189
+ name: "".concat(field, ".id"),
190
+ children: /*#__PURE__*/jsx(HiddenInput, {
191
+ hiddenValue: id
192
+ })
193
+ }), /*#__PURE__*/jsx(Controller, {
194
+ name: "".concat(field, ".datatype"),
195
+ children: /*#__PURE__*/jsx(Select, {
196
+ inline: true,
197
+ label: "Type",
198
+ placeholder: "Data type",
199
+ options: acceptableTypes,
200
+ onChange: function onChange(val) {
201
+ return handleTypeChange(val);
202
+ }
203
+ })
204
+ }), /*#__PURE__*/jsx(Controller, {
205
+ name: "".concat(field, ".label"),
206
+ children: /*#__PURE__*/jsx(Input, {
207
+ inline: true,
208
+ label: "Label",
209
+ allowClear: true,
210
+ placeholder: "Label...",
211
+ decorateEndShowWhenEmpty: true,
212
+ decorateEnd: /*#__PURE__*/jsx("span", {
213
+ className: "text-sm text-tint-300 px-1",
214
+ children: "OPTIONAL"
215
+ })
216
+ })
217
+ }), type === DATA_TYPES.STRING && /*#__PURE__*/jsxs(Fragment, {
218
+ children: [/*#__PURE__*/jsx(Controller, {
219
+ name: "".concat(field, ".regex"),
220
+ children: /*#__PURE__*/jsx(Input, {
221
+ inline: true,
222
+ label: "Regex validation",
223
+ allowClear: true,
224
+ placeholder: "Regex value...",
225
+ decorateEndShowWhenEmpty: true,
226
+ decorateEnd: /*#__PURE__*/jsx("span", {
227
+ className: "text-sm text-tint-300 px-1",
228
+ children: "OPTIONAL"
229
+ })
230
+ })
231
+ }), /*#__PURE__*/jsxs(Field, {
232
+ inline: true,
233
+ label: "Option list",
234
+ children: [/*#__PURE__*/jsx(Controller, {
235
+ name: "".concat(field, ".optionList"),
236
+ children: /*#__PURE__*/jsx(Select, {
237
+ allowClear: true,
238
+ options: [SCHEMA_CUSTOM_LIST].concat(_toConsumableArray(optionLists)),
239
+ onChange: function onChange(v) {
240
+ return setCustomOptions(v === SCHEMA_CUSTOM_LIST);
241
+ }
242
+ })
243
+ }), customOptions && /*#__PURE__*/jsx(Button, {
244
+ icon: CoreIcons.list,
245
+ "aria-label": "Custom options",
246
+ onClick: function onClick() {
247
+ void openOptionModal({
248
+ title: "".concat(id, " Options")
249
+ });
250
+ }
251
+ })]
252
+ }), OptionModal]
253
+ }), type === DATA_TYPES.FILE && /*#__PURE__*/jsx(Fragment, {
254
+ children: /*#__PURE__*/jsx(Controller, {
255
+ name: "".concat(field, ".accept"),
256
+ children: /*#__PURE__*/jsx(Input, {
257
+ inline: true,
258
+ label: "Accept types",
259
+ allowClear: true,
260
+ placeholder: "Accept value...",
261
+ decorateEndShowWhenEmpty: true,
262
+ decorateEnd: /*#__PURE__*/jsx("span", {
263
+ className: "text-sm text-tint-300 px-1",
264
+ children: "OPTIONAL"
265
+ })
266
+ })
267
+ })
268
+ }), [DATA_TYPES.NUMBER, DATA_TYPES.RANGE].includes(type) && /*#__PURE__*/jsxs(Fragment, {
269
+ children: [/*#__PURE__*/jsx(Controller, {
270
+ name: "".concat(field, ".min"),
271
+ children: /*#__PURE__*/jsx(Number, {
272
+ inline: true,
273
+ label: "Min value",
274
+ allowClear: true,
275
+ placeholder: "Minimum value...",
276
+ decorateEndShowWhenEmpty: true,
277
+ decorateEnd: /*#__PURE__*/jsx("span", {
278
+ className: "text-sm text-tint-300 px-1",
279
+ children: "OPTIONAL"
280
+ })
281
+ })
282
+ }), /*#__PURE__*/jsx(Controller, {
283
+ name: "".concat(field, ".max"),
284
+ children: /*#__PURE__*/jsx(Number, {
285
+ inline: true,
286
+ label: "Max value",
287
+ allowClear: true,
288
+ placeholder: "Maximum value...",
289
+ decorateEndShowWhenEmpty: true,
290
+ decorateEnd: /*#__PURE__*/jsx("span", {
291
+ className: "text-sm text-tint-300 px-1",
292
+ children: "OPTIONAL"
293
+ })
294
+ })
295
+ }), /*#__PURE__*/jsx(Controller, {
296
+ name: "".concat(field, ".step"),
297
+ children: /*#__PURE__*/jsx(Number, {
298
+ inline: true,
299
+ label: "Step value",
300
+ allowClear: true,
301
+ placeholder: "Step value...",
302
+ decorateEndShowWhenEmpty: true,
303
+ decorateEnd: /*#__PURE__*/jsx("span", {
304
+ className: "text-sm text-tint-300 px-1",
305
+ children: "OPTIONAL"
306
+ })
307
+ })
308
+ })]
309
+ }), type === DATA_TYPES.DATE && /*#__PURE__*/jsxs(Fragment, {
310
+ children: [/*#__PURE__*/jsx(Field, {
311
+ inline: true,
312
+ label: "Type",
313
+ plain: true,
314
+ children: /*#__PURE__*/jsx(Controller, {
315
+ name: "".concat(field, ".type"),
316
+ children: /*#__PURE__*/jsxs(ToggleButtonGroup, {
317
+ value: "",
318
+ fullWidth: true,
319
+ className: "flex-1",
320
+ children: [/*#__PURE__*/jsx(Button, {
321
+ className: "flex-1",
322
+ value: "date",
323
+ children: "Date"
324
+ }), /*#__PURE__*/jsx(Button, {
325
+ className: "flex-1",
326
+ value: "datetime",
327
+ children: "Date Time"
328
+ })]
329
+ })
330
+ })
331
+ }), /*#__PURE__*/jsx(Controller, {
332
+ name: "".concat(field, ".min"),
333
+ children: /*#__PURE__*/jsx(DateInput, {
334
+ inline: true,
335
+ label: "Min value",
336
+ allowClear: true,
337
+ placeholder: "Minimum value...",
338
+ decorateEndShowWhenEmpty: true,
339
+ decorateEnd: /*#__PURE__*/jsx("span", {
340
+ className: "text-sm text-tint-300 px-1",
341
+ children: "OPTIONAL"
342
+ })
343
+ })
344
+ }), /*#__PURE__*/jsx(Controller, {
345
+ name: "".concat(field, ".max"),
346
+ children: /*#__PURE__*/jsx(DateInput, {
347
+ inline: true,
348
+ label: "Max value",
349
+ allowClear: true,
350
+ placeholder: "Maximum value...",
351
+ decorateEndShowWhenEmpty: true,
352
+ decorateEnd: /*#__PURE__*/jsx("span", {
353
+ className: "text-sm text-tint-300 px-1",
354
+ children: "OPTIONAL"
355
+ })
356
+ })
357
+ })]
358
+ }), /*#__PURE__*/jsxs(Field, {
359
+ label: " ",
360
+ inline: true,
361
+ plain: true,
362
+ children: [/*#__PURE__*/jsx(Controller, {
363
+ name: "".concat(field, ".required"),
364
+ children: /*#__PURE__*/jsx(Checkbox, {
365
+ label: "Required"
366
+ })
367
+ }), type !== DATA_TYPES.AVATAR && /*#__PURE__*/jsx(Controller, {
368
+ name: "".concat(field, ".multiple"),
369
+ children: /*#__PURE__*/jsx(Checkbox, {
370
+ label: "Multiple",
371
+ onChange: setMultiple
372
+ })
373
+ }), hasOptions && /*#__PURE__*/jsx(Controller, {
374
+ name: "".concat(field, ".allowCustom"),
375
+ children: /*#__PURE__*/jsx(Checkbox, {
376
+ label: "Allow custom value"
377
+ })
378
+ })]
379
+ }), multiple && /*#__PURE__*/jsxs(Fragment, {
380
+ children: [/*#__PURE__*/jsx(Controller, {
381
+ name: "".concat(field, ".minItems"),
382
+ children: /*#__PURE__*/jsx(Number, {
383
+ inline: true,
384
+ label: "Min items",
385
+ allowClear: true,
386
+ placeholder: "Minimum items...",
387
+ decorateEndShowWhenEmpty: true,
388
+ decorateEnd: /*#__PURE__*/jsx("span", {
389
+ className: "text-sm text-tint-300 px-1",
390
+ children: "OPTIONAL"
391
+ })
392
+ })
393
+ }), /*#__PURE__*/jsx(Controller, {
394
+ name: "".concat(field, ".maxItems"),
395
+ children: /*#__PURE__*/jsx(Number, {
396
+ inline: true,
397
+ label: "Max items",
398
+ allowClear: true,
399
+ placeholder: "Maximum items...",
400
+ decorateEndShowWhenEmpty: true,
401
+ decorateEnd: /*#__PURE__*/jsx("span", {
402
+ className: "text-sm text-tint-300 px-1",
403
+ children: "OPTIONAL"
404
+ })
405
+ })
406
+ })]
407
+ })]
408
+ })]
409
+ }, fieldId)
410
+ });
411
+ };
412
+
413
+ export { SchemaField };
@@ -46,7 +46,7 @@ var Controller = function Controller(_ref) {
46
46
  (_children$props$onCha = (_children$props = children.props).onChange) === null || _children$props$onCha === void 0 || _children$props$onCha.call(_children$props, v);
47
47
  }
48
48
  })) : children(_objectSpread(_objectSpread(_objectSpread({}, field), rest), {}, {
49
- inputRef: function inputRef(el) {
49
+ ref: function ref(el) {
50
50
  el && _ref3(el);
51
51
  },
52
52
  readOnly: isSubmitting,
@@ -7,6 +7,7 @@ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProper
7
7
  import _regeneratorRuntime from '@babel/runtime/regenerator';
8
8
  import { yupResolver } from '@hookform/resolvers/yup';
9
9
  import { useDebounce } from '@react-fabric/core';
10
+ import { EMPTY_OBJECT } from '@react-fabric/utilities';
10
11
  import { useRef, useTransition, useEffect, useCallback, useImperativeHandle } from 'react';
11
12
  import { useForm, FormProvider } from 'react-hook-form';
12
13
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -21,9 +22,10 @@ var Form = function Form(_ref) {
21
22
  var formRef = _ref.formRef,
22
23
  schema = _ref.schema,
23
24
  children = _ref.children,
24
- defaultValues = _ref.defaultValues,
25
+ _ref$defaultValues = _ref.defaultValues,
26
+ defaultValues = _ref$defaultValues === void 0 ? EMPTY_OBJECT : _ref$defaultValues,
25
27
  _ref$onSubmit = _ref.onSubmit,
26
- onSubmit = _ref$onSubmit === void 0 ? DEFAULT_SUBMIT : _ref$onSubmit,
28
+ _onSubmit = _ref$onSubmit === void 0 ? DEFAULT_SUBMIT : _ref$onSubmit,
27
29
  onChange = _ref.onChange,
28
30
  rest = _objectWithoutProperties(_ref, _excluded);
29
31
  var ref = useRef(null);
@@ -63,7 +65,7 @@ var Form = function Form(_ref) {
63
65
  return handleReset();
64
66
  },
65
67
  submit: function submit() {
66
- return form.handleSubmit(onSubmit);
68
+ return form.handleSubmit(_onSubmit);
67
69
  },
68
70
  validate: function () {
69
71
  var _validate = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
@@ -89,16 +91,20 @@ var Form = function Form(_ref) {
89
91
  return form.getValues();
90
92
  },
91
93
  setValues: function setValues(v) {
92
- return form.reset(v);
94
+ return setTimeout(function () {
95
+ return form.reset(v);
96
+ }, 50);
93
97
  },
94
98
  setValue: function setValue(k, v) {
95
- return form.setValue(k, v, {
96
- shouldDirty: false,
97
- shouldTouch: false
98
- });
99
+ return setTimeout(function () {
100
+ return form.setValue(k, v, {
101
+ shouldDirty: false,
102
+ shouldTouch: false
103
+ });
104
+ }, 50);
99
105
  }
100
106
  };
101
- }, [onSubmit, form, form.formState, defaultValues]);
107
+ }, [_onSubmit, form, form.formState, defaultValues]);
102
108
  var onInvalid = useCallback(function (_, e) {
103
109
  var el = e.target;
104
110
  setTimeout(function () {
@@ -112,7 +118,10 @@ var Form = function Form(_ref) {
112
118
  onReset: function onReset() {
113
119
  return handleReset(defaultValues);
114
120
  },
115
- onSubmit: form.handleSubmit(onSubmit, onInvalid),
121
+ onSubmit: function onSubmit(e) {
122
+ e.stopPropagation();
123
+ void form.handleSubmit(_onSubmit, onInvalid)(e);
124
+ },
116
125
  "data-loading": form.formState.isSubmitting,
117
126
  className: "contents",
118
127
  autoComplete: "off"
@@ -1,33 +1,42 @@
1
1
  'use client';
2
2
 
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
+ import { EmptyContent } from '@react-fabric/core';
4
5
  import { yup, isNil, isEmpty } from '@react-fabric/utilities';
5
6
  import { useMemo, Fragment } from 'react';
6
7
  import { FormField } from '../builder/FormField.js';
7
- import { jsx } from 'react/jsx-runtime';
8
+ import { DATA_TYPES } from '../types/schema.js';
9
+ import { jsxs, jsx } from 'react/jsx-runtime';
8
10
 
9
11
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
12
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11
13
  var makeYupField = function makeYupField(field) {
12
- var yupField = yup.string();
13
- if (field.datatype === "schema") {
14
+ var yupField = yup.string().trim();
15
+ if (field.datatype === DATA_TYPES.SCHEMA) {
14
16
  var child = Object.fromEntries(field.schema.map(function (field) {
15
17
  return [field.id, makeYupField(field)];
16
18
  }));
17
19
  yupField = yup.object(child);
18
20
  }
19
- if (field.datatype === "boolean") yupField = yup["boolean"]();
20
- if (field.datatype === "decimal" || field.datatype === "number" || field.datatype === "range") {
21
+ if (field.datatype === DATA_TYPES.BOOL) {
22
+ yupField = yup["boolean"]();
23
+ if (field.required) yupField = yupField.test({
24
+ test: function test(value) {
25
+ return !!value;
26
+ }
27
+ });
28
+ }
29
+ if (field.datatype === DATA_TYPES.NUMBER || field.datatype === DATA_TYPES.RANGE) {
21
30
  yupField = yup.number();
22
31
  !isNil(field.min) && (yupField = yupField.min(field.min));
23
32
  !isNil(field.max) && (yupField = yupField.max(field.max));
24
- if (field.datatype === "range") yupField = yup.array(yupField);
33
+ if (field.datatype === DATA_TYPES.RANGE) yupField = yup.array(yupField);
25
34
  }
26
- if (field.datatype === "string") {
27
- field.options && (yupField = yupField.oneOf(field.options));
35
+ if (field.datatype === DATA_TYPES.STRING) {
36
+ field.options && !field.allowCustom && (yupField = yupField.oneOf(field.options));
28
37
  field.regex && (yupField = yupField.matches(new RegExp(field.regex)));
29
38
  }
30
- if (field.datatype === "file") {
39
+ if (field.datatype === DATA_TYPES.FILE) {
31
40
  yupField = yup.object({
32
41
  filename: yup.string().required(),
33
42
  path: yup.string().required()
@@ -64,19 +73,22 @@ var useFormBuilder = function useFormBuilder(schema) {
64
73
  var schemaDef = yup.object(Object.fromEntries(filteredSchema.map(function (field) {
65
74
  return [field.id, makeYupField(field)];
66
75
  })));
67
- var formDef = /*#__PURE__*/jsx(Fragment, {
68
- children: filteredSchema.map(function (field, idx) {
76
+ var formDef = /*#__PURE__*/jsxs(Fragment, {
77
+ children: [filteredSchema.map(function (field, idx) {
69
78
  return /*#__PURE__*/jsx("div", {
70
79
  className: "mb-4",
71
- children: field.datatype === "schema" ? null : /*#__PURE__*/jsx(FormField, _objectSpread(_objectSpread({}, field), {}, {
80
+ children: field.datatype === DATA_TYPES.SCHEMA ? null : /*#__PURE__*/jsx(FormField, _objectSpread(_objectSpread({}, field), {}, {
72
81
  autoFocus: idx === 0,
73
82
  fileUrl: options.fileUrl,
83
+ optionLists: options.optionLists,
74
84
  uploadHandler: options.uploadHandler,
75
85
  inline: options.inline,
76
86
  prefix: options.prefix
77
87
  }))
78
88
  }, field.id);
79
- })
89
+ }), filteredSchema.length === 0 && /*#__PURE__*/jsx(EmptyContent, {
90
+ message: "No schema defined"
91
+ })]
80
92
  });
81
93
  return {
82
94
  formDef: formDef,
package/dist/esm/index.js CHANGED
@@ -3,12 +3,15 @@
3
3
  import './i18n/index.js';
4
4
  export { Controller } from './form/Controller.js';
5
5
  export { Form } from './form/Form.js';
6
+ export { SchemaEditor } from './builder/SchemaEditor.js';
6
7
  export { useFileUploader } from './hooks/useFileUploader.js';
7
8
  export { useFormBuilder } from './hooks/useFormBuilder.js';
9
+ export { DATA_TYPES, SCHEMA_CUSTOM_LIST } from './types/schema.js';
8
10
  export { ArrayInput } from './input/ArrayInput.js';
9
11
  export { Checkbox } from './input/Checkbox.js';
10
12
  export { ColorInput } from './input/ColorInput.js';
11
13
  export { ColorPicker } from './input/ColorPicker.js';
14
+ export { DateInput } from './input/DateInput.js';
12
15
  export { Field } from './input/Field.js';
13
16
  export { FileInput } from './input/File.js';
14
17
  export { HiddenInput } from './input/Hidden.js';
@@ -17,7 +20,7 @@ export { Number } from './input/Number.js';
17
20
  export { Password } from './input/Password.js';
18
21
  export { Radio } from './input/Radio.js';
19
22
  export { RadioGroup } from './input/RadioGroup.js';
20
- export { Range } from './input/Range.js';
23
+ export { RangeSlider } from './input/RangeSlider.js';
21
24
  export { Search } from './input/Search.js';
22
25
  export { Slider } from './input/Slider.js';
23
26
  export { Switch } from './input/Switch.js';