@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 CHANGED
@@ -68,6 +68,7 @@
68
68
  & input,
69
69
  & textarea {
70
70
  max-width: 100%;
71
+ line-height: 1;
71
72
  }
72
73
 
73
74
  & > input[type="number"] + .inputClear {
@@ -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", "fixedList", "focusName", "buttonPosition", "onAdd", "onRemove", "onBeforeRemove", "canRemove", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems", "maxItems"];
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: !fixedList && onAdd && buttonPosition !== "bottom" && addButton
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
- }), !fixedList && /*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
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 || (canRemove === null || canRemove === void 0 ? void 0 : canRemove({
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
- })), !fixedList && onAdd && buttonPosition !== "top" && addButton]
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 rounded-full relative outline overflow-hidden",
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/20 hover:bg-black/50 text-white text-xs text-center py-1",
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: core$1.CoreIcons.chevronsLeft,
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: core$1.CoreIcons.chevronLeft,
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: core$1.CoreIcons.chevronRight,
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: core$1.CoreIcons.chevronsRight,
227
+ icon: {
228
+ icon: core$1.CoreIcons.chevronsRight,
229
+ rtlFlip: true
230
+ },
223
231
  disabled: !leftOptions.length
224
232
  })]
225
233
  })
@@ -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", "fixedList", "focusName", "buttonPosition", "onAdd", "onRemove", "onBeforeRemove", "canRemove", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems", "maxItems"];
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: !fixedList && onAdd && buttonPosition !== "bottom" && addButton
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
- }), !fixedList && /*#__PURE__*/jsx(Button, {
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 || (canRemove === null || canRemove === void 0 ? void 0 : canRemove({
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
- })), !fixedList && onAdd && buttonPosition !== "top" && addButton]
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 rounded-full relative outline overflow-hidden",
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/20 hover:bg-black/50 text-white text-xs text-center py-1",
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: CoreIcons.chevronsLeft,
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: CoreIcons.chevronLeft,
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: CoreIcons.chevronRight,
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: CoreIcons.chevronsRight,
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 {};
@@ -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?: () => AnyObject;
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, fixedList, focusName, buttonPosition, onAdd, onRemove, onBeforeRemove, canRemove, arrayRef, enableSorting, disabled, readOnly, minItems, maxItems, ...rest }: ArrayInputProps<T>) => import("react/jsx-runtime").JSX.Element;
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.57",
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": "^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.9",
43
- "@hookform/resolvers": "^3.9.0",
44
- "@react-fabric/core": "^1.0.0-beta.57",
45
- "@react-fabric/date": "^1.0.0-beta.57",
46
- "@react-fabric/utilities": "^1.0.0-beta.52",
47
- "classnames": "^2.5.1",
48
- "color": "^4.2.3",
49
- "react-color": "^2.19.3",
50
- "react-hook-form": "^7.52.1"
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": "^25.2.1",
54
- "react": "^19.0.0",
55
- "react-dom": "^19.0.0",
56
- "react-i18next": "^15.5.2"
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/axios": "^0.14.0",
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": "9b596a0a8d6cecaa8479f80c495b64fb42ce739f"
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
- useForm,
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 = useForm<K>({
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
@@ -24,7 +24,7 @@
24
24
  import "./i18n";
25
25
 
26
26
  export { Controller } from "./form/Controller";
27
- export { Form, type FormRef } from "./form/Form";
27
+ export { Form, useForm, type FormRef } from "./form/Form";
28
28
 
29
29
  export { SchemaEditor } from "./builder/SchemaEditor";
30
30
 
@@ -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?: () => AnyObject;
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?: (props: { item: T; index: number; lastItem: boolean }) => boolean;
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: T) => {
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("fabric-addButton", "me-10")}
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
- [error, fields, handleAdd, disabled, readOnly, addLabel, maxItems],
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
- {!fixedList && onAdd && buttonPosition !== "bottom" && addButton}
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
- {!fixedList && (
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
- canRemove?.({
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 T, index)}
457
+ onClick={() => handleRemove(item as any, index)}
424
458
  />
425
459
  )}
426
460
  </SortableItem>
427
461
  ))}
428
462
  </Wrapper>
429
463
  </FieldWrapper>
430
- {!fixedList && onAdd && buttonPosition !== "top" && addButton}
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 className="inline-block leading-none rounded-full relative outline overflow-hidden">
121
- <Avatar name={avatarName ?? "temp"} size={size} avatar={base64} />
122
- <div className="absolute inset-x-0 bottom-0 cursor-pointer bg-black/20 hover:bg-black/50 text-white text-xs text-center py-1">
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"
@@ -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>