@react-fabric/form 1.0.0-beta.57 → 1.0.0-beta.58
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.
- package/css/_field.css +1 -0
- package/dist/cjs/form/Form.js +24 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/input/ArrayInput.js +34 -13
- package/dist/cjs/input/AvatarInput.js +13 -4
- package/dist/cjs/select/DualList.js +16 -8
- package/dist/esm/form/Form.js +26 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/input/ArrayInput.js +35 -14
- package/dist/esm/input/AvatarInput.js +13 -4
- package/dist/esm/select/DualList.js +16 -8
- package/dist/types/form/Form.d.ts +11 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/input/ArrayInput.d.ts +5 -8
- package/dist/types/input/AvatarInput.d.ts +6 -1
- package/package.json +20 -21
- package/src/form/Form.tsx +34 -2
- package/src/index.ts +1 -1
- package/src/input/ArrayInput.tsx +55 -21
- package/src/input/AvatarInput.tsx +27 -3
- package/src/select/DualList.tsx +4 -8
package/css/_field.css
CHANGED
package/dist/cjs/form/Form.js
CHANGED
|
@@ -165,5 +165,29 @@ var Form = function Form(_ref) {
|
|
|
165
165
|
}))
|
|
166
166
|
}));
|
|
167
167
|
};
|
|
168
|
+
var useForm = function useForm() {
|
|
169
|
+
var _useFormContext = reactHookForm.useFormContext(),
|
|
170
|
+
formState = _useFormContext.formState,
|
|
171
|
+
getValues = _useFormContext.getValues,
|
|
172
|
+
setValue = _useFormContext.setValue,
|
|
173
|
+
watch = _useFormContext.watch,
|
|
174
|
+
reset = _useFormContext.reset,
|
|
175
|
+
resetField = _useFormContext.resetField,
|
|
176
|
+
setError = _useFormContext.setError,
|
|
177
|
+
setFocus = _useFormContext.setFocus;
|
|
178
|
+
var values = reactHookForm.useWatch();
|
|
179
|
+
return {
|
|
180
|
+
values: _objectSpread(_objectSpread({}, values), getValues()),
|
|
181
|
+
formState: formState,
|
|
182
|
+
getValues: getValues,
|
|
183
|
+
setValue: setValue,
|
|
184
|
+
watch: watch,
|
|
185
|
+
reset: reset,
|
|
186
|
+
resetField: resetField,
|
|
187
|
+
setError: setError,
|
|
188
|
+
setFocus: setFocus
|
|
189
|
+
};
|
|
190
|
+
};
|
|
168
191
|
|
|
169
192
|
exports.Form = Form;
|
|
193
|
+
exports.useForm = useForm;
|
package/dist/cjs/index.js
CHANGED
|
@@ -35,6 +35,7 @@ var Select = require('./select/Select.js');
|
|
|
35
35
|
|
|
36
36
|
exports.Controller = Controller.Controller;
|
|
37
37
|
exports.Form = Form.Form;
|
|
38
|
+
exports.useForm = Form.useForm;
|
|
38
39
|
exports.SchemaEditor = SchemaEditor.SchemaEditor;
|
|
39
40
|
exports.useFileUploader = useFileUploader.useFileUploader;
|
|
40
41
|
exports.useFormBuilder = useFormBuilder.useFormBuilder;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
4
|
+
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
|
|
4
5
|
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
|
|
5
6
|
var core = require('@dnd-kit/core');
|
|
6
7
|
var sortable = require('@dnd-kit/sortable');
|
|
@@ -15,7 +16,7 @@ var modifiers = require('@dnd-kit/modifiers');
|
|
|
15
16
|
var utilities$1 = require('@dnd-kit/utilities');
|
|
16
17
|
var jsxRuntime = require('react/jsx-runtime');
|
|
17
18
|
|
|
18
|
-
var _excluded = ["name", "children", "addLabel", "
|
|
19
|
+
var _excluded = ["name", "children", "addLabel", "focusName", "buttonPosition", "onAdd", "onRemove", "onBeforeRemove", "canRemove", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems", "maxItems"];
|
|
19
20
|
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; }
|
|
20
21
|
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; }
|
|
21
22
|
/**
|
|
@@ -61,7 +62,6 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
61
62
|
var name = _ref.name,
|
|
62
63
|
children = _ref.children,
|
|
63
64
|
addLabel = _ref.addLabel,
|
|
64
|
-
fixedList = _ref.fixedList,
|
|
65
65
|
_ref$focusName = _ref.focusName,
|
|
66
66
|
focusName = _ref$focusName === void 0 ? "" : _ref$focusName,
|
|
67
67
|
_ref$buttonPosition = _ref.buttonPosition,
|
|
@@ -94,11 +94,35 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
94
94
|
append = _useFieldArray.append,
|
|
95
95
|
remove = _useFieldArray.remove,
|
|
96
96
|
move = _useFieldArray.move;
|
|
97
|
+
var _useState = react.useState([]),
|
|
98
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
99
|
+
initialList = _useState2[0],
|
|
100
|
+
setInitialList = _useState2[1];
|
|
101
|
+
react.useEffect(function () {
|
|
102
|
+
setInitialList(fields.map(function (f) {
|
|
103
|
+
return f.__ID__;
|
|
104
|
+
}));
|
|
105
|
+
}, []);
|
|
97
106
|
var error = react.useMemo(function () {
|
|
98
107
|
var _form$formState$error, _form$formState$error2, _form$formState$error3;
|
|
99
108
|
return (_form$formState$error = (_form$formState$error2 = form.formState.errors[name]) === null || _form$formState$error2 === void 0 ? void 0 : _form$formState$error2.message) !== null && _form$formState$error !== void 0 ? _form$formState$error : (_form$formState$error3 = form.formState.errors[name]) === null || _form$formState$error3 === void 0 || (_form$formState$error3 = _form$formState$error3.root) === null || _form$formState$error3 === void 0 ? void 0 : _form$formState$error3.message;
|
|
100
109
|
}, [form.formState.errors]);
|
|
110
|
+
var removeCheck = react.useCallback(function (item, index) {
|
|
111
|
+
if (canRemove === false) return false;
|
|
112
|
+
if (canRemove === "newonly") {
|
|
113
|
+
return initialList.includes(item.__ID__) ? false : true;
|
|
114
|
+
}
|
|
115
|
+
if (typeof canRemove === "function") {
|
|
116
|
+
return canRemove({
|
|
117
|
+
item: item,
|
|
118
|
+
index: index,
|
|
119
|
+
lastItem: index + 1 === fields.length
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
}, [canRemove, initialList, fields]);
|
|
101
124
|
var handleAdd = react.useCallback(function (item) {
|
|
125
|
+
if (!item) return;
|
|
102
126
|
append(item);
|
|
103
127
|
setTimeout(function () {
|
|
104
128
|
form.setFocus("".concat(name, ".").concat(fields.length).concat(focusName ? "." + focusName : ""));
|
|
@@ -199,18 +223,18 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
199
223
|
},
|
|
200
224
|
"data-invalid": !!error,
|
|
201
225
|
disabled: !!disabled || readOnly || fields.length > maxItems,
|
|
202
|
-
className: classNames("fabric-addButton", "me-10"),
|
|
203
|
-
children: addLabel !== null && addLabel !== void 0 ? addLabel : t("addArray")
|
|
226
|
+
className: classNames("fabric-addButton", canRemove !== false && "me-10"),
|
|
227
|
+
children: addLabel !== null && addLabel !== void 0 ? addLabel : t("form:addArray")
|
|
204
228
|
})
|
|
205
229
|
})
|
|
206
230
|
});
|
|
207
|
-
}, [error, fields, handleAdd, disabled, readOnly, addLabel, maxItems]);
|
|
231
|
+
}, [error, fields, handleAdd, canRemove, disabled, readOnly, addLabel, maxItems]);
|
|
208
232
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
209
233
|
className: "fabric-arrayInput",
|
|
210
234
|
children: [/*#__PURE__*/jsxRuntime.jsx(FieldWrapper.FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
|
|
211
235
|
appendLabel: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
212
236
|
className: "-me-2",
|
|
213
|
-
children:
|
|
237
|
+
children: onAdd && buttonPosition !== "bottom" && addButton
|
|
214
238
|
}),
|
|
215
239
|
children: /*#__PURE__*/jsxRuntime.jsx(Wrapper, {
|
|
216
240
|
children: fields.map(function (item, index) {
|
|
@@ -219,6 +243,7 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
219
243
|
className: "flex items-center flex-nowrap gap-2 mb-1",
|
|
220
244
|
children: [typeof children === "function" ? children({
|
|
221
245
|
index: index,
|
|
246
|
+
item: item,
|
|
222
247
|
name: "".concat(name, ".").concat(index)
|
|
223
248
|
}) : core$1.cloneChildren(children, function (child) {
|
|
224
249
|
return /*#__PURE__*/react.cloneElement(child, Object.assign({
|
|
@@ -231,17 +256,13 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
231
256
|
required: undefined,
|
|
232
257
|
appendLabel: undefined
|
|
233
258
|
}));
|
|
234
|
-
}),
|
|
259
|
+
}), canRemove !== false && /*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
|
|
235
260
|
"aria-label": "Remove item",
|
|
236
261
|
icon: core$1.CoreIcons.remove,
|
|
237
262
|
color: "danger",
|
|
238
263
|
variant: "link",
|
|
239
264
|
className: "self-end",
|
|
240
|
-
disabled: disabled || readOnly || fields.length <= minItems || (
|
|
241
|
-
item: item,
|
|
242
|
-
index: index,
|
|
243
|
-
lastItem: index + 1 === fields.length
|
|
244
|
-
})) !== false,
|
|
265
|
+
disabled: disabled || readOnly || fields.length <= minItems || removeCheck(item, index) === false,
|
|
245
266
|
onClick: function onClick() {
|
|
246
267
|
return handleRemove(item, index);
|
|
247
268
|
}
|
|
@@ -249,7 +270,7 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
249
270
|
}, item.__ID__);
|
|
250
271
|
})
|
|
251
272
|
})
|
|
252
|
-
})),
|
|
273
|
+
})), onAdd && buttonPosition !== "top" && addButton]
|
|
253
274
|
});
|
|
254
275
|
};
|
|
255
276
|
|
|
@@ -9,9 +9,10 @@ var core = require('@react-fabric/core');
|
|
|
9
9
|
var react = require('react');
|
|
10
10
|
var useFileUploader = require('../hooks/useFileUploader.js');
|
|
11
11
|
var Hidden = require('./Hidden.js');
|
|
12
|
+
var classNames = require('classnames');
|
|
12
13
|
var jsxRuntime = require('react/jsx-runtime');
|
|
13
14
|
|
|
14
|
-
var _excluded = ["size", "avatarName", "value", "defaultValue", "fileUrl", "uploadHandler"];
|
|
15
|
+
var _excluded = ["size", "avatarName", "avatarClassName", "value", "rounded", "defaultValue", "fallbackIcon", "variant", "fileUrl", "uploadHandler"];
|
|
15
16
|
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; }
|
|
16
17
|
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; }
|
|
17
18
|
/**
|
|
@@ -27,8 +28,12 @@ var AvatarInput = function AvatarInput(_ref) {
|
|
|
27
28
|
var _ref$size = _ref.size,
|
|
28
29
|
size = _ref$size === void 0 ? "6rem" : _ref$size,
|
|
29
30
|
avatarName = _ref.avatarName,
|
|
31
|
+
avatarClassName = _ref.avatarClassName,
|
|
30
32
|
value = _ref.value,
|
|
33
|
+
rounded = _ref.rounded,
|
|
31
34
|
defaultValue = _ref.defaultValue,
|
|
35
|
+
fallbackIcon = _ref.fallbackIcon,
|
|
36
|
+
variant = _ref.variant,
|
|
32
37
|
fileUrl = _ref.fileUrl,
|
|
33
38
|
uploadHandler = _ref.uploadHandler,
|
|
34
39
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
@@ -86,13 +91,17 @@ var AvatarInput = function AvatarInput(_ref) {
|
|
|
86
91
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
87
92
|
className: "flex flex-nowrap items-end overflow-hidden",
|
|
88
93
|
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
89
|
-
className: "inline-block leading-none
|
|
94
|
+
className: classNames("inline-block leading-none relative outline overflow-hidden", rounded && "rounded-full", !rounded && "rounded"),
|
|
90
95
|
children: [/*#__PURE__*/jsxRuntime.jsx(core.Avatar, {
|
|
91
96
|
name: avatarName !== null && avatarName !== void 0 ? avatarName : "temp",
|
|
92
97
|
size: size,
|
|
93
|
-
avatar: base64
|
|
98
|
+
avatar: base64,
|
|
99
|
+
rounded: rounded,
|
|
100
|
+
variant: variant,
|
|
101
|
+
fallbackIcon: fallbackIcon,
|
|
102
|
+
className: avatarClassName
|
|
94
103
|
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
95
|
-
className: "absolute inset-x-0 bottom-0 cursor-pointer bg-black/
|
|
104
|
+
className: "absolute inset-x-0 bottom-0 cursor-pointer opacity-50 bg-black/50 hover:opacity-90 text-white text-xs text-center py-1",
|
|
96
105
|
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
97
106
|
children: "Edit"
|
|
98
107
|
}), /*#__PURE__*/jsxRuntime.jsx("input", {
|
|
@@ -190,36 +190,44 @@ var DualList = function DualList(_ref) {
|
|
|
190
190
|
vertical: true,
|
|
191
191
|
className: "outline overflow-hidden bg-base",
|
|
192
192
|
children: [/*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
|
|
193
|
-
rtlFlip: true,
|
|
194
193
|
size: "sm",
|
|
195
194
|
variant: "link",
|
|
196
195
|
"aria-label": "scroll to top",
|
|
197
196
|
onClick: moveAllLeft,
|
|
198
|
-
icon:
|
|
197
|
+
icon: {
|
|
198
|
+
icon: core$1.CoreIcons.chevronsLeft,
|
|
199
|
+
rtlFlip: true
|
|
200
|
+
},
|
|
199
201
|
disabled: !rightOptions.length
|
|
200
202
|
}), /*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
|
|
201
|
-
rtlFlip: true,
|
|
202
203
|
size: "sm",
|
|
203
204
|
variant: "link",
|
|
204
205
|
"aria-label": "scroll up",
|
|
205
206
|
onClick: moveRightSelected,
|
|
206
|
-
icon:
|
|
207
|
+
icon: {
|
|
208
|
+
icon: core$1.CoreIcons.chevronLeft,
|
|
209
|
+
rtlFlip: true
|
|
210
|
+
},
|
|
207
211
|
disabled: !rightSelected.length
|
|
208
212
|
}), /*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
|
|
209
|
-
rtlFlip: true,
|
|
210
213
|
size: "sm",
|
|
211
214
|
variant: "link",
|
|
212
215
|
"aria-label": "scroll down",
|
|
213
216
|
onClick: moveLeftSelected,
|
|
214
|
-
icon:
|
|
217
|
+
icon: {
|
|
218
|
+
icon: core$1.CoreIcons.chevronRight,
|
|
219
|
+
rtlFlip: true
|
|
220
|
+
},
|
|
215
221
|
disabled: !leftSelected.length
|
|
216
222
|
}), /*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
|
|
217
|
-
rtlFlip: true,
|
|
218
223
|
size: "sm",
|
|
219
224
|
variant: "link",
|
|
220
225
|
"aria-label": "scroll to bottom",
|
|
221
226
|
onClick: moveAllRight,
|
|
222
|
-
icon:
|
|
227
|
+
icon: {
|
|
228
|
+
icon: core$1.CoreIcons.chevronsRight,
|
|
229
|
+
rtlFlip: true
|
|
230
|
+
},
|
|
223
231
|
disabled: !leftOptions.length
|
|
224
232
|
})]
|
|
225
233
|
})
|
package/dist/esm/form/Form.js
CHANGED
|
@@ -9,7 +9,7 @@ import { yupResolver } from '@hookform/resolvers/yup';
|
|
|
9
9
|
import { useDebounce } from '@react-fabric/core';
|
|
10
10
|
import { EMPTY_OBJECT } from '@react-fabric/utilities';
|
|
11
11
|
import { useRef, useTransition, useEffect, useCallback, useImperativeHandle } from 'react';
|
|
12
|
-
import { useForm, FormProvider } from 'react-hook-form';
|
|
12
|
+
import { useForm as useForm$1, FormProvider, useFormContext, useWatch } from 'react-hook-form';
|
|
13
13
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
14
14
|
|
|
15
15
|
var _excluded = ["formRef", "schema", "children", "defaultValues", "onSubmit", "onChange"];
|
|
@@ -61,7 +61,7 @@ var Form = function Form(_ref) {
|
|
|
61
61
|
onChange = _ref.onChange,
|
|
62
62
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
63
63
|
var ref = useRef(null);
|
|
64
|
-
var form = useForm({
|
|
64
|
+
var form = useForm$1({
|
|
65
65
|
shouldFocusError: true,
|
|
66
66
|
resolver: schema && yupResolver(schema),
|
|
67
67
|
defaultValues: defaultValues
|
|
@@ -165,5 +165,28 @@ var Form = function Form(_ref) {
|
|
|
165
165
|
}))
|
|
166
166
|
}));
|
|
167
167
|
};
|
|
168
|
+
var useForm = function useForm() {
|
|
169
|
+
var _useFormContext = useFormContext(),
|
|
170
|
+
formState = _useFormContext.formState,
|
|
171
|
+
getValues = _useFormContext.getValues,
|
|
172
|
+
setValue = _useFormContext.setValue,
|
|
173
|
+
watch = _useFormContext.watch,
|
|
174
|
+
reset = _useFormContext.reset,
|
|
175
|
+
resetField = _useFormContext.resetField,
|
|
176
|
+
setError = _useFormContext.setError,
|
|
177
|
+
setFocus = _useFormContext.setFocus;
|
|
178
|
+
var values = useWatch();
|
|
179
|
+
return {
|
|
180
|
+
values: _objectSpread(_objectSpread({}, values), getValues()),
|
|
181
|
+
formState: formState,
|
|
182
|
+
getValues: getValues,
|
|
183
|
+
setValue: setValue,
|
|
184
|
+
watch: watch,
|
|
185
|
+
reset: reset,
|
|
186
|
+
resetField: resetField,
|
|
187
|
+
setError: setError,
|
|
188
|
+
setFocus: setFocus
|
|
189
|
+
};
|
|
190
|
+
};
|
|
168
191
|
|
|
169
|
-
export { Form };
|
|
192
|
+
export { Form, useForm };
|
package/dist/esm/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import './i18n/index.js';
|
|
4
4
|
export { Controller } from './form/Controller.js';
|
|
5
|
-
export { Form } from './form/Form.js';
|
|
5
|
+
export { Form, useForm } from './form/Form.js';
|
|
6
6
|
export { SchemaEditor } from './builder/SchemaEditor.js';
|
|
7
7
|
export { useFileUploader } from './hooks/useFileUploader.js';
|
|
8
8
|
export { useFormBuilder } from './hooks/useFormBuilder.js';
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
4
|
+
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
4
5
|
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
5
6
|
import { DndContext } from '@dnd-kit/core';
|
|
6
7
|
import { SortableContext, useSortable } from '@dnd-kit/sortable';
|
|
7
8
|
import { Icon, CoreIcons, Tooltip, Button, cloneChildren } from '@react-fabric/core';
|
|
8
9
|
import { isFalse, isString } from '@react-fabric/utilities';
|
|
9
10
|
import classNames from 'classnames';
|
|
10
|
-
import { useMemo, useCallback, useImperativeHandle, cloneElement } from 'react';
|
|
11
|
+
import { useState, useEffect, useMemo, useCallback, useImperativeHandle, cloneElement } from 'react';
|
|
11
12
|
import { useFormContext, useFieldArray } from 'react-hook-form';
|
|
12
13
|
import { useTranslation } from 'react-i18next';
|
|
13
14
|
import { FieldWrapper } from '../internal/FieldWrapper.js';
|
|
@@ -15,7 +16,7 @@ import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
|
|
|
15
16
|
import { CSS } from '@dnd-kit/utilities';
|
|
16
17
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
17
18
|
|
|
18
|
-
var _excluded = ["name", "children", "addLabel", "
|
|
19
|
+
var _excluded = ["name", "children", "addLabel", "focusName", "buttonPosition", "onAdd", "onRemove", "onBeforeRemove", "canRemove", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems", "maxItems"];
|
|
19
20
|
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; }
|
|
20
21
|
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; }
|
|
21
22
|
/**
|
|
@@ -61,7 +62,6 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
61
62
|
var name = _ref.name,
|
|
62
63
|
children = _ref.children,
|
|
63
64
|
addLabel = _ref.addLabel,
|
|
64
|
-
fixedList = _ref.fixedList,
|
|
65
65
|
_ref$focusName = _ref.focusName,
|
|
66
66
|
focusName = _ref$focusName === void 0 ? "" : _ref$focusName,
|
|
67
67
|
_ref$buttonPosition = _ref.buttonPosition,
|
|
@@ -94,11 +94,35 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
94
94
|
append = _useFieldArray.append,
|
|
95
95
|
remove = _useFieldArray.remove,
|
|
96
96
|
move = _useFieldArray.move;
|
|
97
|
+
var _useState = useState([]),
|
|
98
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
99
|
+
initialList = _useState2[0],
|
|
100
|
+
setInitialList = _useState2[1];
|
|
101
|
+
useEffect(function () {
|
|
102
|
+
setInitialList(fields.map(function (f) {
|
|
103
|
+
return f.__ID__;
|
|
104
|
+
}));
|
|
105
|
+
}, []);
|
|
97
106
|
var error = useMemo(function () {
|
|
98
107
|
var _form$formState$error, _form$formState$error2, _form$formState$error3;
|
|
99
108
|
return (_form$formState$error = (_form$formState$error2 = form.formState.errors[name]) === null || _form$formState$error2 === void 0 ? void 0 : _form$formState$error2.message) !== null && _form$formState$error !== void 0 ? _form$formState$error : (_form$formState$error3 = form.formState.errors[name]) === null || _form$formState$error3 === void 0 || (_form$formState$error3 = _form$formState$error3.root) === null || _form$formState$error3 === void 0 ? void 0 : _form$formState$error3.message;
|
|
100
109
|
}, [form.formState.errors]);
|
|
110
|
+
var removeCheck = useCallback(function (item, index) {
|
|
111
|
+
if (canRemove === false) return false;
|
|
112
|
+
if (canRemove === "newonly") {
|
|
113
|
+
return initialList.includes(item.__ID__) ? false : true;
|
|
114
|
+
}
|
|
115
|
+
if (typeof canRemove === "function") {
|
|
116
|
+
return canRemove({
|
|
117
|
+
item: item,
|
|
118
|
+
index: index,
|
|
119
|
+
lastItem: index + 1 === fields.length
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
}, [canRemove, initialList, fields]);
|
|
101
124
|
var handleAdd = useCallback(function (item) {
|
|
125
|
+
if (!item) return;
|
|
102
126
|
append(item);
|
|
103
127
|
setTimeout(function () {
|
|
104
128
|
form.setFocus("".concat(name, ".").concat(fields.length).concat(focusName ? "." + focusName : ""));
|
|
@@ -199,18 +223,18 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
199
223
|
},
|
|
200
224
|
"data-invalid": !!error,
|
|
201
225
|
disabled: !!disabled || readOnly || fields.length > maxItems,
|
|
202
|
-
className: classNames("fabric-addButton", "me-10"),
|
|
203
|
-
children: addLabel !== null && addLabel !== void 0 ? addLabel : t("addArray")
|
|
226
|
+
className: classNames("fabric-addButton", canRemove !== false && "me-10"),
|
|
227
|
+
children: addLabel !== null && addLabel !== void 0 ? addLabel : t("form:addArray")
|
|
204
228
|
})
|
|
205
229
|
})
|
|
206
230
|
});
|
|
207
|
-
}, [error, fields, handleAdd, disabled, readOnly, addLabel, maxItems]);
|
|
231
|
+
}, [error, fields, handleAdd, canRemove, disabled, readOnly, addLabel, maxItems]);
|
|
208
232
|
return /*#__PURE__*/jsxs("div", {
|
|
209
233
|
className: "fabric-arrayInput",
|
|
210
234
|
children: [/*#__PURE__*/jsx(FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
|
|
211
235
|
appendLabel: /*#__PURE__*/jsx("div", {
|
|
212
236
|
className: "-me-2",
|
|
213
|
-
children:
|
|
237
|
+
children: onAdd && buttonPosition !== "bottom" && addButton
|
|
214
238
|
}),
|
|
215
239
|
children: /*#__PURE__*/jsx(Wrapper, {
|
|
216
240
|
children: fields.map(function (item, index) {
|
|
@@ -219,6 +243,7 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
219
243
|
className: "flex items-center flex-nowrap gap-2 mb-1",
|
|
220
244
|
children: [typeof children === "function" ? children({
|
|
221
245
|
index: index,
|
|
246
|
+
item: item,
|
|
222
247
|
name: "".concat(name, ".").concat(index)
|
|
223
248
|
}) : cloneChildren(children, function (child) {
|
|
224
249
|
return /*#__PURE__*/cloneElement(child, Object.assign({
|
|
@@ -231,17 +256,13 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
231
256
|
required: undefined,
|
|
232
257
|
appendLabel: undefined
|
|
233
258
|
}));
|
|
234
|
-
}),
|
|
259
|
+
}), canRemove !== false && /*#__PURE__*/jsx(Button, {
|
|
235
260
|
"aria-label": "Remove item",
|
|
236
261
|
icon: CoreIcons.remove,
|
|
237
262
|
color: "danger",
|
|
238
263
|
variant: "link",
|
|
239
264
|
className: "self-end",
|
|
240
|
-
disabled: disabled || readOnly || fields.length <= minItems || (
|
|
241
|
-
item: item,
|
|
242
|
-
index: index,
|
|
243
|
-
lastItem: index + 1 === fields.length
|
|
244
|
-
})) !== false,
|
|
265
|
+
disabled: disabled || readOnly || fields.length <= minItems || removeCheck(item, index) === false,
|
|
245
266
|
onClick: function onClick() {
|
|
246
267
|
return handleRemove(item, index);
|
|
247
268
|
}
|
|
@@ -249,7 +270,7 @@ var ArrayInput = function ArrayInput(_ref) {
|
|
|
249
270
|
}, item.__ID__);
|
|
250
271
|
})
|
|
251
272
|
})
|
|
252
|
-
})),
|
|
273
|
+
})), onAdd && buttonPosition !== "top" && addButton]
|
|
253
274
|
});
|
|
254
275
|
};
|
|
255
276
|
|
|
@@ -9,9 +9,10 @@ import { Avatar, Icon, CoreIcons, ProgressBar } from '@react-fabric/core';
|
|
|
9
9
|
import { useState, useEffect } from 'react';
|
|
10
10
|
import { useFileUploader } from '../hooks/useFileUploader.js';
|
|
11
11
|
import { HiddenInput } from './Hidden.js';
|
|
12
|
+
import classNames from 'classnames';
|
|
12
13
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
13
14
|
|
|
14
|
-
var _excluded = ["size", "avatarName", "value", "defaultValue", "fileUrl", "uploadHandler"];
|
|
15
|
+
var _excluded = ["size", "avatarName", "avatarClassName", "value", "rounded", "defaultValue", "fallbackIcon", "variant", "fileUrl", "uploadHandler"];
|
|
15
16
|
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; }
|
|
16
17
|
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; }
|
|
17
18
|
/**
|
|
@@ -27,8 +28,12 @@ var AvatarInput = function AvatarInput(_ref) {
|
|
|
27
28
|
var _ref$size = _ref.size,
|
|
28
29
|
size = _ref$size === void 0 ? "6rem" : _ref$size,
|
|
29
30
|
avatarName = _ref.avatarName,
|
|
31
|
+
avatarClassName = _ref.avatarClassName,
|
|
30
32
|
value = _ref.value,
|
|
33
|
+
rounded = _ref.rounded,
|
|
31
34
|
defaultValue = _ref.defaultValue,
|
|
35
|
+
fallbackIcon = _ref.fallbackIcon,
|
|
36
|
+
variant = _ref.variant,
|
|
32
37
|
fileUrl = _ref.fileUrl,
|
|
33
38
|
uploadHandler = _ref.uploadHandler,
|
|
34
39
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
@@ -86,13 +91,17 @@ var AvatarInput = function AvatarInput(_ref) {
|
|
|
86
91
|
return /*#__PURE__*/jsxs("div", {
|
|
87
92
|
className: "flex flex-nowrap items-end overflow-hidden",
|
|
88
93
|
children: [/*#__PURE__*/jsxs("div", {
|
|
89
|
-
className: "inline-block leading-none
|
|
94
|
+
className: classNames("inline-block leading-none relative outline overflow-hidden", rounded && "rounded-full", !rounded && "rounded"),
|
|
90
95
|
children: [/*#__PURE__*/jsx(Avatar, {
|
|
91
96
|
name: avatarName !== null && avatarName !== void 0 ? avatarName : "temp",
|
|
92
97
|
size: size,
|
|
93
|
-
avatar: base64
|
|
98
|
+
avatar: base64,
|
|
99
|
+
rounded: rounded,
|
|
100
|
+
variant: variant,
|
|
101
|
+
fallbackIcon: fallbackIcon,
|
|
102
|
+
className: avatarClassName
|
|
94
103
|
}), /*#__PURE__*/jsxs("div", {
|
|
95
|
-
className: "absolute inset-x-0 bottom-0 cursor-pointer bg-black/
|
|
104
|
+
className: "absolute inset-x-0 bottom-0 cursor-pointer opacity-50 bg-black/50 hover:opacity-90 text-white text-xs text-center py-1",
|
|
96
105
|
children: [/*#__PURE__*/jsx("span", {
|
|
97
106
|
children: "Edit"
|
|
98
107
|
}), /*#__PURE__*/jsx("input", {
|
|
@@ -190,36 +190,44 @@ var DualList = function DualList(_ref) {
|
|
|
190
190
|
vertical: true,
|
|
191
191
|
className: "outline overflow-hidden bg-base",
|
|
192
192
|
children: [/*#__PURE__*/jsx(Button, {
|
|
193
|
-
rtlFlip: true,
|
|
194
193
|
size: "sm",
|
|
195
194
|
variant: "link",
|
|
196
195
|
"aria-label": "scroll to top",
|
|
197
196
|
onClick: moveAllLeft,
|
|
198
|
-
icon:
|
|
197
|
+
icon: {
|
|
198
|
+
icon: CoreIcons.chevronsLeft,
|
|
199
|
+
rtlFlip: true
|
|
200
|
+
},
|
|
199
201
|
disabled: !rightOptions.length
|
|
200
202
|
}), /*#__PURE__*/jsx(Button, {
|
|
201
|
-
rtlFlip: true,
|
|
202
203
|
size: "sm",
|
|
203
204
|
variant: "link",
|
|
204
205
|
"aria-label": "scroll up",
|
|
205
206
|
onClick: moveRightSelected,
|
|
206
|
-
icon:
|
|
207
|
+
icon: {
|
|
208
|
+
icon: CoreIcons.chevronLeft,
|
|
209
|
+
rtlFlip: true
|
|
210
|
+
},
|
|
207
211
|
disabled: !rightSelected.length
|
|
208
212
|
}), /*#__PURE__*/jsx(Button, {
|
|
209
|
-
rtlFlip: true,
|
|
210
213
|
size: "sm",
|
|
211
214
|
variant: "link",
|
|
212
215
|
"aria-label": "scroll down",
|
|
213
216
|
onClick: moveLeftSelected,
|
|
214
|
-
icon:
|
|
217
|
+
icon: {
|
|
218
|
+
icon: CoreIcons.chevronRight,
|
|
219
|
+
rtlFlip: true
|
|
220
|
+
},
|
|
215
221
|
disabled: !leftSelected.length
|
|
216
222
|
}), /*#__PURE__*/jsx(Button, {
|
|
217
|
-
rtlFlip: true,
|
|
218
223
|
size: "sm",
|
|
219
224
|
variant: "link",
|
|
220
225
|
"aria-label": "scroll to bottom",
|
|
221
226
|
onClick: moveAllRight,
|
|
222
|
-
icon:
|
|
227
|
+
icon: {
|
|
228
|
+
icon: CoreIcons.chevronsRight,
|
|
229
|
+
rtlFlip: true
|
|
230
|
+
},
|
|
223
231
|
disabled: !leftOptions.length
|
|
224
232
|
})]
|
|
225
233
|
})
|
|
@@ -65,4 +65,15 @@ export interface FormProps<K extends KeyValue = KeyValue> {
|
|
|
65
65
|
* @see {@link https://github.com/jquense/yup} for more details on the Yup validation schema.
|
|
66
66
|
*/
|
|
67
67
|
export declare const Form: <K extends KeyValue>({ formRef, schema, children, defaultValues, onSubmit, onChange, ...rest }: PropsWithChildren<FormProps<K>>) => import("react/jsx-runtime").JSX.Element;
|
|
68
|
+
export declare const useForm: <K extends KeyValue = KeyValue>() => {
|
|
69
|
+
values: import("react-hook-form").DeepPartialSkipArrayKey<K> & K;
|
|
70
|
+
formState: FormState<K>;
|
|
71
|
+
getValues: import("react-hook-form").UseFormGetValues<K>;
|
|
72
|
+
setValue: import("react-hook-form").UseFormSetValue<K>;
|
|
73
|
+
watch: import("react-hook-form").UseFormWatch<K>;
|
|
74
|
+
reset: import("react-hook-form").UseFormReset<K>;
|
|
75
|
+
resetField: import("react-hook-form").UseFormResetField<K>;
|
|
76
|
+
setError: import("react-hook-form").UseFormSetError<K>;
|
|
77
|
+
setFocus: import("react-hook-form").UseFormSetFocus<K>;
|
|
78
|
+
};
|
|
68
79
|
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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
4
|
export { SchemaEditor } from "./builder/SchemaEditor";
|
|
5
5
|
export { useFileUploader } from "./hooks/useFileUploader";
|
|
6
6
|
export { useFormBuilder } from "./hooks/useFormBuilder";
|
|
@@ -47,16 +47,13 @@ export interface ArrayInputProps<T extends AnyObject = string> {
|
|
|
47
47
|
children: React.ReactNode | ((props: {
|
|
48
48
|
index: number;
|
|
49
49
|
name: string;
|
|
50
|
+
item: T;
|
|
50
51
|
}) => ReactNode);
|
|
51
52
|
/**
|
|
52
53
|
* add item button label
|
|
53
54
|
*/
|
|
54
55
|
addLabel?: string;
|
|
55
56
|
buttonPosition?: "top" | "bottom" | "both";
|
|
56
|
-
/**
|
|
57
|
-
* fixed length list
|
|
58
|
-
*/
|
|
59
|
-
fixedList?: boolean;
|
|
60
57
|
arrayRef?: Ref<{
|
|
61
58
|
addItem: (item: T) => void;
|
|
62
59
|
removeItem: (idx: number) => void;
|
|
@@ -64,7 +61,7 @@ export interface ArrayInputProps<T extends AnyObject = string> {
|
|
|
64
61
|
/**
|
|
65
62
|
* add new item
|
|
66
63
|
*/
|
|
67
|
-
onAdd?: () =>
|
|
64
|
+
onAdd?: () => T;
|
|
68
65
|
/**
|
|
69
66
|
* on item remove
|
|
70
67
|
*/
|
|
@@ -76,11 +73,11 @@ export interface ArrayInputProps<T extends AnyObject = string> {
|
|
|
76
73
|
/**
|
|
77
74
|
* can remove item
|
|
78
75
|
*/
|
|
79
|
-
canRemove?: (props: {
|
|
76
|
+
canRemove?: false | "newonly" | ((props: {
|
|
80
77
|
item: T;
|
|
81
78
|
index: number;
|
|
82
79
|
lastItem: boolean;
|
|
83
|
-
}) => boolean;
|
|
80
|
+
}) => boolean);
|
|
84
81
|
/**
|
|
85
82
|
* field width
|
|
86
83
|
*/
|
|
@@ -133,4 +130,4 @@ export interface ArrayInputProps<T extends AnyObject = string> {
|
|
|
133
130
|
* @see {@link https://react-hook-form.com/api/usefieldarray} for more details on `useFieldArray`.
|
|
134
131
|
* @see {@link https://react-dnd.github.io/react-dnd/about} for more details on DnD context and sorting.
|
|
135
132
|
*/
|
|
136
|
-
export declare const ArrayInput: <T extends AnyObject = string>({ name, children, addLabel,
|
|
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;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type RefProp } from "@react-fabric/core/dist/types/types";
|
|
2
2
|
import { type UploadHandler } from "../hooks/useFileUploader";
|
|
3
|
+
import { AvatarProps } from "@react-fabric/core/dist/types/components/avatar/Avatar";
|
|
3
4
|
export interface Props extends RefProp {
|
|
4
5
|
/**
|
|
5
6
|
* field name
|
|
@@ -17,6 +18,10 @@ export interface Props extends RefProp {
|
|
|
17
18
|
* avatar name
|
|
18
19
|
*/
|
|
19
20
|
avatarName?: string;
|
|
21
|
+
rounded?: boolean;
|
|
22
|
+
variant?: AvatarProps["variant"];
|
|
23
|
+
fallbackIcon?: AvatarProps["fallbackIcon"];
|
|
24
|
+
avatarClassName?: AvatarProps["className"];
|
|
20
25
|
size?: string | number;
|
|
21
26
|
/**
|
|
22
27
|
* upload handler to store file in temp storage
|
|
@@ -43,4 +48,4 @@ export interface Props extends RefProp {
|
|
|
43
48
|
* @param {Props} props - The properties for the AvatarInput component.
|
|
44
49
|
* @returns {JSX.Element} - The rendered AvatarInput component.
|
|
45
50
|
*/
|
|
46
|
-
export declare const AvatarInput: ({ size, avatarName, value, defaultValue, fileUrl, uploadHandler, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export declare const AvatarInput: ({ size, avatarName, avatarClassName, value, rounded, defaultValue, fallbackIcon, variant, fileUrl, uploadHandler, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-fabric/form",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.58",
|
|
4
4
|
"description": "RUF: Form package",
|
|
5
5
|
"author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,33 +35,32 @@
|
|
|
35
35
|
"watch": "npm-run-all -p watch:rollup watch:dts"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@dnd-kit/core": "
|
|
39
|
-
"@dnd-kit/modifiers": "
|
|
40
|
-
"@dnd-kit/sortable": "
|
|
41
|
-
"@dnd-kit/utilities": "
|
|
42
|
-
"@floating-ui/react": "
|
|
43
|
-
"@hookform/resolvers": "
|
|
44
|
-
"@react-fabric/core": "^1.0.0-beta.
|
|
45
|
-
"@react-fabric/date": "^1.0.0-beta.
|
|
46
|
-
"@react-fabric/utilities": "^1.0.0-beta.
|
|
47
|
-
"classnames": "
|
|
48
|
-
"color": "
|
|
49
|
-
"react-color": "
|
|
50
|
-
"react-hook-form": "
|
|
38
|
+
"@dnd-kit/core": "~6.3.1",
|
|
39
|
+
"@dnd-kit/modifiers": "~9.0.0",
|
|
40
|
+
"@dnd-kit/sortable": "~10.0.0",
|
|
41
|
+
"@dnd-kit/utilities": "~3.2.2",
|
|
42
|
+
"@floating-ui/react": "~0.27.16",
|
|
43
|
+
"@hookform/resolvers": "~5.2.2",
|
|
44
|
+
"@react-fabric/core": "^1.0.0-beta.58",
|
|
45
|
+
"@react-fabric/date": "^1.0.0-beta.58",
|
|
46
|
+
"@react-fabric/utilities": "^1.0.0-beta.58",
|
|
47
|
+
"classnames": "~2.5.1",
|
|
48
|
+
"color": "~5.0.2",
|
|
49
|
+
"react-color": "~2.19.3",
|
|
50
|
+
"react-hook-form": "~7.65.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"i18next": "
|
|
54
|
-
"react": "
|
|
55
|
-
"react-dom": "
|
|
56
|
-
"react-i18next": "
|
|
53
|
+
"i18next": "~25.6.0",
|
|
54
|
+
"react": "~19.2.0",
|
|
55
|
+
"react-dom": "~19.2.0",
|
|
56
|
+
"react-i18next": "~16.2.1"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@types/
|
|
60
|
-
"@types/react-color": "^3.0.12"
|
|
59
|
+
"@types/react-color": "~3.0.13"
|
|
61
60
|
},
|
|
62
61
|
"engines": {
|
|
63
62
|
"node": ">=18.12.0",
|
|
64
63
|
"npm": ">=8.19.0"
|
|
65
64
|
},
|
|
66
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "7e66f8c498e37a40e410ecafff2ea6b31505dc1a"
|
|
67
66
|
}
|
package/src/form/Form.tsx
CHANGED
|
@@ -29,13 +29,16 @@ import {
|
|
|
29
29
|
useEffect,
|
|
30
30
|
useImperativeHandle,
|
|
31
31
|
useRef,
|
|
32
|
+
useState,
|
|
32
33
|
useTransition,
|
|
33
34
|
type PropsWithChildren,
|
|
34
35
|
type Ref,
|
|
35
36
|
} from "react";
|
|
36
37
|
import {
|
|
37
38
|
FormProvider,
|
|
38
|
-
|
|
39
|
+
useFormContext,
|
|
40
|
+
useForm as useFormHook,
|
|
41
|
+
useWatch,
|
|
39
42
|
type DefaultValues,
|
|
40
43
|
type FormState,
|
|
41
44
|
} from "react-hook-form";
|
|
@@ -120,7 +123,7 @@ export const Form = <K extends KeyValue>({
|
|
|
120
123
|
...rest
|
|
121
124
|
}: PropsWithChildren<FormProps<K>>) => {
|
|
122
125
|
const ref = useRef<HTMLFormElement>(null);
|
|
123
|
-
const form =
|
|
126
|
+
const form = useFormHook<K>({
|
|
124
127
|
shouldFocusError: true,
|
|
125
128
|
resolver: schema && (yupResolver(schema) as AnyObject),
|
|
126
129
|
defaultValues: defaultValues as DefaultValues<K>,
|
|
@@ -202,3 +205,32 @@ export const Form = <K extends KeyValue>({
|
|
|
202
205
|
</FormProvider>
|
|
203
206
|
);
|
|
204
207
|
};
|
|
208
|
+
|
|
209
|
+
export const useForm = <K extends KeyValue = KeyValue>() => {
|
|
210
|
+
const {
|
|
211
|
+
formState,
|
|
212
|
+
getValues,
|
|
213
|
+
setValue,
|
|
214
|
+
watch,
|
|
215
|
+
reset,
|
|
216
|
+
resetField,
|
|
217
|
+
setError,
|
|
218
|
+
setFocus,
|
|
219
|
+
} = useFormContext<K>();
|
|
220
|
+
const values = useWatch<K>();
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
values: {
|
|
224
|
+
...values,
|
|
225
|
+
...getValues(),
|
|
226
|
+
},
|
|
227
|
+
formState,
|
|
228
|
+
getValues,
|
|
229
|
+
setValue,
|
|
230
|
+
watch,
|
|
231
|
+
reset,
|
|
232
|
+
resetField,
|
|
233
|
+
setError,
|
|
234
|
+
setFocus,
|
|
235
|
+
};
|
|
236
|
+
};
|
package/src/index.ts
CHANGED
package/src/input/ArrayInput.tsx
CHANGED
|
@@ -34,9 +34,12 @@ import { isFalse, isString } from "@react-fabric/utilities";
|
|
|
34
34
|
import classNames from "classnames";
|
|
35
35
|
import {
|
|
36
36
|
cloneElement,
|
|
37
|
+
use,
|
|
37
38
|
useCallback,
|
|
39
|
+
useEffect,
|
|
38
40
|
useImperativeHandle,
|
|
39
41
|
useMemo,
|
|
42
|
+
useState,
|
|
40
43
|
type PropsWithChildren,
|
|
41
44
|
type ReactNode,
|
|
42
45
|
type Ref,
|
|
@@ -96,16 +99,12 @@ export interface ArrayInputProps<T extends AnyObject = string> {
|
|
|
96
99
|
enableSorting?: boolean;
|
|
97
100
|
children:
|
|
98
101
|
| React.ReactNode
|
|
99
|
-
| ((props: { index: number; name: string }) => ReactNode);
|
|
102
|
+
| ((props: { index: number; name: string; item: T }) => ReactNode);
|
|
100
103
|
/**
|
|
101
104
|
* add item button label
|
|
102
105
|
*/
|
|
103
106
|
addLabel?: string;
|
|
104
107
|
buttonPosition?: "top" | "bottom" | "both";
|
|
105
|
-
/**
|
|
106
|
-
* fixed length list
|
|
107
|
-
*/
|
|
108
|
-
fixedList?: boolean;
|
|
109
108
|
arrayRef?: Ref<{
|
|
110
109
|
addItem: (item: T) => void;
|
|
111
110
|
removeItem: (idx: number) => void;
|
|
@@ -113,7 +112,7 @@ export interface ArrayInputProps<T extends AnyObject = string> {
|
|
|
113
112
|
/**
|
|
114
113
|
* add new item
|
|
115
114
|
*/
|
|
116
|
-
onAdd?: () =>
|
|
115
|
+
onAdd?: () => T;
|
|
117
116
|
/**
|
|
118
117
|
* on item remove
|
|
119
118
|
*/
|
|
@@ -125,7 +124,10 @@ export interface ArrayInputProps<T extends AnyObject = string> {
|
|
|
125
124
|
/**
|
|
126
125
|
* can remove item
|
|
127
126
|
*/
|
|
128
|
-
canRemove?:
|
|
127
|
+
canRemove?:
|
|
128
|
+
| false
|
|
129
|
+
| "newonly"
|
|
130
|
+
| ((props: { item: T; index: number; lastItem: boolean }) => boolean);
|
|
129
131
|
|
|
130
132
|
/**
|
|
131
133
|
* field width
|
|
@@ -184,7 +186,6 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
184
186
|
name,
|
|
185
187
|
children,
|
|
186
188
|
addLabel,
|
|
187
|
-
fixedList,
|
|
188
189
|
focusName = "",
|
|
189
190
|
buttonPosition = "bottom",
|
|
190
191
|
onAdd,
|
|
@@ -211,6 +212,11 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
211
212
|
control: form.control,
|
|
212
213
|
});
|
|
213
214
|
|
|
215
|
+
const [initialList, setInitialList] = useState<string[]>([]);
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
setInitialList(fields.map((f) => f.__ID__));
|
|
218
|
+
}, []);
|
|
219
|
+
|
|
214
220
|
const error = useMemo<AnyObject>(
|
|
215
221
|
() =>
|
|
216
222
|
form.formState.errors[name]?.message ??
|
|
@@ -218,8 +224,27 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
218
224
|
[form.formState.errors],
|
|
219
225
|
);
|
|
220
226
|
|
|
227
|
+
const removeCheck = useCallback(
|
|
228
|
+
(item: T, index: number) => {
|
|
229
|
+
if (canRemove === false) return false;
|
|
230
|
+
if (canRemove === "newonly") {
|
|
231
|
+
return initialList.includes((item as any).__ID__) ? false : true;
|
|
232
|
+
}
|
|
233
|
+
if (typeof canRemove === "function") {
|
|
234
|
+
return canRemove({
|
|
235
|
+
item,
|
|
236
|
+
index,
|
|
237
|
+
lastItem: index + 1 === fields.length,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
},
|
|
242
|
+
[canRemove, initialList, fields],
|
|
243
|
+
);
|
|
244
|
+
|
|
221
245
|
const handleAdd = useCallback(
|
|
222
|
-
(item
|
|
246
|
+
(item?: T) => {
|
|
247
|
+
if (!item) return;
|
|
223
248
|
append(item);
|
|
224
249
|
setTimeout(() => {
|
|
225
250
|
form.setFocus(
|
|
@@ -349,14 +374,26 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
349
374
|
onClick={() => handleAdd(onAdd?.())}
|
|
350
375
|
data-invalid={!!error}
|
|
351
376
|
disabled={!!disabled || readOnly || fields.length > maxItems}
|
|
352
|
-
className={classNames(
|
|
377
|
+
className={classNames(
|
|
378
|
+
"fabric-addButton",
|
|
379
|
+
canRemove !== false && "me-10",
|
|
380
|
+
)}
|
|
353
381
|
>
|
|
354
|
-
{addLabel ?? t("addArray")}
|
|
382
|
+
{addLabel ?? t("form:addArray")}
|
|
355
383
|
</Button>
|
|
356
384
|
</Tooltip>
|
|
357
385
|
</div>
|
|
358
386
|
),
|
|
359
|
-
[
|
|
387
|
+
[
|
|
388
|
+
error,
|
|
389
|
+
fields,
|
|
390
|
+
handleAdd,
|
|
391
|
+
canRemove,
|
|
392
|
+
disabled,
|
|
393
|
+
readOnly,
|
|
394
|
+
addLabel,
|
|
395
|
+
maxItems,
|
|
396
|
+
],
|
|
360
397
|
);
|
|
361
398
|
|
|
362
399
|
return (
|
|
@@ -365,7 +402,7 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
365
402
|
{...rest}
|
|
366
403
|
appendLabel={
|
|
367
404
|
<div className="-me-2">
|
|
368
|
-
{
|
|
405
|
+
{onAdd && buttonPosition !== "bottom" && addButton}
|
|
369
406
|
</div>
|
|
370
407
|
}
|
|
371
408
|
>
|
|
@@ -379,6 +416,7 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
379
416
|
{typeof children === "function"
|
|
380
417
|
? children({
|
|
381
418
|
index,
|
|
419
|
+
item: item as any,
|
|
382
420
|
name: `${name}.${index}`,
|
|
383
421
|
})
|
|
384
422
|
: cloneChildren(children, (child: AnyObject) =>
|
|
@@ -403,7 +441,7 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
403
441
|
),
|
|
404
442
|
),
|
|
405
443
|
)}
|
|
406
|
-
{
|
|
444
|
+
{canRemove !== false && (
|
|
407
445
|
<Button
|
|
408
446
|
aria-label="Remove item"
|
|
409
447
|
icon={CoreIcons.remove}
|
|
@@ -414,20 +452,16 @@ export const ArrayInput = <T extends AnyObject = string>({
|
|
|
414
452
|
disabled ||
|
|
415
453
|
readOnly ||
|
|
416
454
|
fields.length <= minItems ||
|
|
417
|
-
|
|
418
|
-
item: item as T,
|
|
419
|
-
index,
|
|
420
|
-
lastItem: index + 1 === fields.length,
|
|
421
|
-
}) !== false
|
|
455
|
+
removeCheck(item as any, index) === false
|
|
422
456
|
}
|
|
423
|
-
onClick={() => handleRemove(item as
|
|
457
|
+
onClick={() => handleRemove(item as any, index)}
|
|
424
458
|
/>
|
|
425
459
|
)}
|
|
426
460
|
</SortableItem>
|
|
427
461
|
))}
|
|
428
462
|
</Wrapper>
|
|
429
463
|
</FieldWrapper>
|
|
430
|
-
{
|
|
464
|
+
{onAdd && buttonPosition !== "top" && addButton}
|
|
431
465
|
</div>
|
|
432
466
|
);
|
|
433
467
|
};
|
|
@@ -26,6 +26,8 @@ import { type RefProp } from "@react-fabric/core/dist/types/types";
|
|
|
26
26
|
import { useEffect, useState } from "react";
|
|
27
27
|
import { useFileUploader, type UploadHandler } from "../hooks/useFileUploader";
|
|
28
28
|
import { HiddenInput } from "./Hidden";
|
|
29
|
+
import { AvatarProps } from "@react-fabric/core/dist/types/components/avatar/Avatar";
|
|
30
|
+
import classNames from "classnames";
|
|
29
31
|
|
|
30
32
|
export interface Props extends RefProp {
|
|
31
33
|
/**
|
|
@@ -44,6 +46,10 @@ export interface Props extends RefProp {
|
|
|
44
46
|
* avatar name
|
|
45
47
|
*/
|
|
46
48
|
avatarName?: string;
|
|
49
|
+
rounded?: boolean;
|
|
50
|
+
variant?: AvatarProps["variant"];
|
|
51
|
+
fallbackIcon?: AvatarProps["fallbackIcon"];
|
|
52
|
+
avatarClassName?: AvatarProps["className"];
|
|
47
53
|
size?: string | number;
|
|
48
54
|
/**
|
|
49
55
|
* upload handler to store file in temp storage
|
|
@@ -74,8 +80,12 @@ export interface Props extends RefProp {
|
|
|
74
80
|
export const AvatarInput = ({
|
|
75
81
|
size = "6rem",
|
|
76
82
|
avatarName,
|
|
83
|
+
avatarClassName,
|
|
77
84
|
value,
|
|
85
|
+
rounded,
|
|
78
86
|
defaultValue,
|
|
87
|
+
fallbackIcon,
|
|
88
|
+
variant,
|
|
79
89
|
fileUrl,
|
|
80
90
|
uploadHandler,
|
|
81
91
|
...rest
|
|
@@ -117,9 +127,23 @@ export const AvatarInput = ({
|
|
|
117
127
|
|
|
118
128
|
return (
|
|
119
129
|
<div className="flex flex-nowrap items-end overflow-hidden">
|
|
120
|
-
<div
|
|
121
|
-
|
|
122
|
-
|
|
130
|
+
<div
|
|
131
|
+
className={classNames(
|
|
132
|
+
"inline-block leading-none relative outline overflow-hidden",
|
|
133
|
+
rounded && "rounded-full",
|
|
134
|
+
!rounded && "rounded",
|
|
135
|
+
)}
|
|
136
|
+
>
|
|
137
|
+
<Avatar
|
|
138
|
+
name={avatarName ?? "temp"}
|
|
139
|
+
size={size}
|
|
140
|
+
avatar={base64}
|
|
141
|
+
rounded={rounded}
|
|
142
|
+
variant={variant}
|
|
143
|
+
fallbackIcon={fallbackIcon}
|
|
144
|
+
className={avatarClassName}
|
|
145
|
+
/>
|
|
146
|
+
<div className="absolute inset-x-0 bottom-0 cursor-pointer opacity-50 bg-black/50 hover:opacity-90 text-white text-xs text-center py-1">
|
|
123
147
|
<span>Edit</span>
|
|
124
148
|
<input
|
|
125
149
|
type="file"
|
package/src/select/DualList.tsx
CHANGED
|
@@ -240,39 +240,35 @@ export const DualList = <T extends AnyObject = string>({
|
|
|
240
240
|
<div className="self-center mx-2">
|
|
241
241
|
<ButtonGroup vertical className="outline overflow-hidden bg-base">
|
|
242
242
|
<Button
|
|
243
|
-
rtlFlip
|
|
244
243
|
size="sm"
|
|
245
244
|
variant="link"
|
|
246
245
|
aria-label="scroll to top"
|
|
247
246
|
onClick={moveAllLeft}
|
|
248
|
-
icon={CoreIcons.chevronsLeft}
|
|
247
|
+
icon={{ icon: CoreIcons.chevronsLeft, rtlFlip: true }}
|
|
249
248
|
disabled={!rightOptions.length}
|
|
250
249
|
/>
|
|
251
250
|
<Button
|
|
252
|
-
rtlFlip
|
|
253
251
|
size="sm"
|
|
254
252
|
variant="link"
|
|
255
253
|
aria-label="scroll up"
|
|
256
254
|
onClick={moveRightSelected}
|
|
257
|
-
icon={CoreIcons.chevronLeft}
|
|
255
|
+
icon={{ icon: CoreIcons.chevronLeft, rtlFlip: true }}
|
|
258
256
|
disabled={!rightSelected.length}
|
|
259
257
|
/>
|
|
260
258
|
<Button
|
|
261
|
-
rtlFlip
|
|
262
259
|
size="sm"
|
|
263
260
|
variant="link"
|
|
264
261
|
aria-label="scroll down"
|
|
265
262
|
onClick={moveLeftSelected}
|
|
266
|
-
icon={CoreIcons.chevronRight}
|
|
263
|
+
icon={{ icon: CoreIcons.chevronRight, rtlFlip: true }}
|
|
267
264
|
disabled={!leftSelected.length}
|
|
268
265
|
/>
|
|
269
266
|
<Button
|
|
270
|
-
rtlFlip
|
|
271
267
|
size="sm"
|
|
272
268
|
variant="link"
|
|
273
269
|
aria-label="scroll to bottom"
|
|
274
270
|
onClick={moveAllRight}
|
|
275
|
-
icon={CoreIcons.chevronsRight}
|
|
271
|
+
icon={{ icon: CoreIcons.chevronsRight, rtlFlip: true }}
|
|
276
272
|
disabled={!leftOptions.length}
|
|
277
273
|
/>
|
|
278
274
|
</ButtonGroup>
|