@react-fabric/form 1.0.0-beta.22 → 1.0.0-beta.24

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.
@@ -16,17 +16,18 @@ var modifiers = require('@dnd-kit/modifiers');
16
16
  var utilities = require('@dnd-kit/utilities');
17
17
  var jsxRuntime = require('react/jsx-runtime');
18
18
 
19
- var _excluded = ["name", "children", "addLabel", "fixedList", "focusName", "onAdd", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems"];
19
+ var _excluded = ["name", "children", "addLabel", "fixedList", "focusName", "buttonPosition", "onAdd", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems", "maxItems"];
20
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; }
21
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; }
22
22
  var ArrayInput = function ArrayInput(_ref) {
23
- var _error$values$label, _error$values, _error$values2;
24
23
  var name = _ref.name,
25
24
  children = _ref.children,
26
25
  addLabel = _ref.addLabel,
27
26
  fixedList = _ref.fixedList,
28
27
  _ref$focusName = _ref.focusName,
29
28
  focusName = _ref$focusName === void 0 ? "" : _ref$focusName,
29
+ _ref$buttonPosition = _ref.buttonPosition,
30
+ buttonPosition = _ref$buttonPosition === void 0 ? "bottom" : _ref$buttonPosition,
30
31
  onAdd = _ref.onAdd,
31
32
  arrayRef = _ref.arrayRef,
32
33
  enableSorting = _ref.enableSorting,
@@ -36,6 +37,8 @@ var ArrayInput = function ArrayInput(_ref) {
36
37
  readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly,
37
38
  _ref$minItems = _ref.minItems,
38
39
  minItems = _ref$minItems === void 0 ? 0 : _ref$minItems,
40
+ _ref$maxItems = _ref.maxItems,
41
+ maxItems = _ref$maxItems === void 0 ? Number.MAX_SAFE_INTEGER : _ref$maxItems,
39
42
  rest = _objectWithoutProperties(_ref, _excluded);
40
43
  var _useTranslation = reactI18next.useTranslation("form"),
41
44
  t = _useTranslation.t;
@@ -127,9 +130,32 @@ var ArrayInput = function ArrayInput(_ref) {
127
130
  }, [enableSorting]);
128
131
  // @ts-expect-error ignore
129
132
  SortableItem.displayName = "SortableItem";
133
+ var addButton = react.useMemo(function () {
134
+ var _error$values$label, _error$values, _error$values2;
135
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
136
+ className: "flex justify-end",
137
+ children: /*#__PURE__*/jsxRuntime.jsx(core$1.Tooltip, {
138
+ color: "danger",
139
+ content: utilities$1.isString(error) ? "".concat(error) : t(error === null || error === void 0 ? void 0 : error.key, error !== null && error !== void 0 && error.values ? _objectSpread(_objectSpread({}, error === null || error === void 0 ? void 0 : error.values), {}, {
140
+ label: t((_error$values$label = (_error$values = error.values) === null || _error$values === void 0 ? void 0 : _error$values.label) !== null && _error$values$label !== void 0 ? _error$values$label : "form:badkey", (_error$values2 = error.values) === null || _error$values2 === void 0 ? void 0 : _error$values2.path)
141
+ }) : {}),
142
+ children: /*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
143
+ "aria-label": "Add item",
144
+ icon: core$1.CoreIcons.insert,
145
+ onClick: function onClick() {
146
+ return handleAdd(onAdd === null || onAdd === void 0 ? void 0 : onAdd());
147
+ },
148
+ "data-invalid": !!error,
149
+ disabled: !!disabled || readOnly || fields.length < maxItems,
150
+ className: classNames(ArrayInput_module.addButton, "me-10"),
151
+ children: addLabel !== null && addLabel !== void 0 ? addLabel : t("addArray")
152
+ })
153
+ })
154
+ });
155
+ }, [error, fields, handleAdd, disabled, readOnly, addLabel, maxItems]);
130
156
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
131
157
  className: ArrayInput_module.arrayInput,
132
- children: [/*#__PURE__*/jsxRuntime.jsx(FieldWrapper.FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
158
+ children: [!fixedList && onAdd && buttonPosition !== "bottom" && addButton, /*#__PURE__*/jsxRuntime.jsx(FieldWrapper.FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
133
159
  children: /*#__PURE__*/jsxRuntime.jsx(Wrapper, {
134
160
  children: fields.map(function (item, index) {
135
161
  return /*#__PURE__*/jsxRuntime.jsxs(SortableItem, {
@@ -138,7 +164,7 @@ var ArrayInput = function ArrayInput(_ref) {
138
164
  children: [typeof children === "function" ? children({
139
165
  index: index,
140
166
  name: "".concat(name, ".").concat(index)
141
- }) : utilities$1.cloneChildren(children, function (child) {
167
+ }) : core$1.cloneChildren(children, function (child) {
142
168
  return /*#__PURE__*/react.cloneElement(child, Object.assign({
143
169
  disabled: disabled,
144
170
  readOnly: readOnly,
@@ -163,26 +189,7 @@ var ArrayInput = function ArrayInput(_ref) {
163
189
  }, item.id);
164
190
  })
165
191
  })
166
- })), !fixedList && onAdd && /*#__PURE__*/jsxRuntime.jsx("div", {
167
- className: "flex justify-end",
168
- children: /*#__PURE__*/jsxRuntime.jsx(core$1.Tooltip, {
169
- color: "danger",
170
- content: utilities$1.isString(error) ? "".concat(error) : t(error === null || error === void 0 ? void 0 : error.key, error !== null && error !== void 0 && error.values ? _objectSpread(_objectSpread({}, error === null || error === void 0 ? void 0 : error.values), {}, {
171
- label: t((_error$values$label = (_error$values = error.values) === null || _error$values === void 0 ? void 0 : _error$values.label) !== null && _error$values$label !== void 0 ? _error$values$label : "form:badkey", (_error$values2 = error.values) === null || _error$values2 === void 0 ? void 0 : _error$values2.path)
172
- }) : {}),
173
- children: /*#__PURE__*/jsxRuntime.jsx(core$1.Button, {
174
- "aria-label": "Add item",
175
- icon: core$1.CoreIcons.insert,
176
- onClick: function onClick() {
177
- return handleAdd(onAdd());
178
- },
179
- "data-invalid": !!error,
180
- disabled: !!disabled || readOnly,
181
- className: classNames(ArrayInput_module.addButton, "me-10"),
182
- children: addLabel !== null && addLabel !== void 0 ? addLabel : t("addArray")
183
- })
184
- })
185
- })]
192
+ })), !fixedList && onAdd && buttonPosition !== "top" && addButton]
186
193
  });
187
194
  };
188
195
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
5
- var utilities = require('@react-fabric/utilities');
5
+ var core = require('@react-fabric/core');
6
6
  var classNames = require('classnames');
7
7
  var react = require('react');
8
8
  var Field_module = require('../internal/Field.module.css');
@@ -21,7 +21,7 @@ var Field = function Field(_ref) {
21
21
  return /*#__PURE__*/jsxRuntime.jsx(FieldWrapper.FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
22
22
  children: /*#__PURE__*/jsxRuntime.jsx("div", {
23
23
  className: classNames(Field_module.fieldGroup, !plain && !noOutline && "outline", !plain && "bg-base", "flex-1 rounded", !vertical && "flex flex-nowrap"),
24
- children: utilities.cloneChildren(children, function (child) {
24
+ children: core.cloneChildren(children, function (child) {
25
25
  return /*#__PURE__*/react.cloneElement(child, {
26
26
  "data-inner": true
27
27
  });
@@ -2,7 +2,7 @@
2
2
 
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
5
- var utilities = require('@react-fabric/utilities');
5
+ var core = require('@react-fabric/core');
6
6
  var react = require('react');
7
7
  var FieldWrapper = require('../internal/FieldWrapper.js');
8
8
  var jsxRuntime = require('react/jsx-runtime');
@@ -20,7 +20,7 @@ var RadioGroup = function RadioGroup(_ref) {
20
20
  return /*#__PURE__*/jsxRuntime.jsx(FieldWrapper.FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
21
21
  children: /*#__PURE__*/jsxRuntime.jsx("div", {
22
22
  className: className,
23
- children: utilities.cloneChildren(children, function (child) {
23
+ children: core.cloneChildren(children, function (child) {
24
24
  return /*#__PURE__*/react.cloneElement(child, {
25
25
  name: name,
26
26
  onChange: onChange,
@@ -34,7 +34,7 @@ var Options = function Options(_ref) {
34
34
  i18nKey: "form:select.emptyList"
35
35
  })
36
36
  })), items.map(function (item, index) {
37
- var _item$labelProperty;
37
+ var _item$value, _item$labelProperty;
38
38
  if (item.___group___) return /*#__PURE__*/jsxRuntime.jsx("p", {
39
39
  className: "px-2 py-1 text-muted text-xs sticky -top-px z-2 bg-base border-t",
40
40
  children: item.label
@@ -51,7 +51,7 @@ var Options = function Options(_ref) {
51
51
  children: /*#__PURE__*/jsxRuntime.jsx(reactI18next.Trans, {
52
52
  i18nKey: "form:select.createOption",
53
53
  values: {
54
- query: item.value
54
+ query: (_item$value = item.value) !== null && _item$value !== void 0 ? _item$value : item
55
55
  },
56
56
  components: [/*#__PURE__*/jsxRuntime.jsx("strong", {
57
57
  children: "query"
@@ -140,6 +140,9 @@ var Select = function Select(_ref) {
140
140
  return false;
141
141
  } else if (state.query) {
142
142
  handleQuery("");
143
+ evt.preventDefault();
144
+ evt.stopPropagation();
145
+ return false;
143
146
  } else {
144
147
  onEnterPressed === null || onEnterPressed === void 0 || onEnterPressed(evt);
145
148
  }
@@ -140,7 +140,7 @@ var useSelect = function useSelect(_ref) {
140
140
  // add new item if allowCreate
141
141
  if (allowCreate && action.query) _newState.items.push({
142
142
  ___create___: true,
143
- value: createOption(action.query)
143
+ value: action.query
144
144
  });
145
145
  Object.entries(grouped).forEach(function (_ref2) {
146
146
  var _newState$items;
@@ -212,7 +212,7 @@ var useSelect = function useSelect(_ref) {
212
212
  var newOption = (allowCreate || autoComplete) && item ? createOption(item) : undefined;
213
213
  var hasValue = options.find(function (opt) {
214
214
  var _opt$valueProperty2;
215
- return ((_opt$valueProperty2 = opt[valueProperty]) !== null && _opt$valueProperty2 !== void 0 ? _opt$valueProperty2 : opt) === deferred;
215
+ return ((_opt$valueProperty2 = opt[valueProperty]) !== null && _opt$valueProperty2 !== void 0 ? _opt$valueProperty2 : opt) === item;
216
216
  });
217
217
  if (!hasValue && newOption) {
218
218
  optionsRef.current.push(newOption);
@@ -4,8 +4,8 @@ import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
5
5
  import { DndContext } from '@dnd-kit/core';
6
6
  import { SortableContext, useSortable } from '@dnd-kit/sortable';
7
- import { Icon, CoreIcons, Button, Tooltip } from '@react-fabric/core';
8
- import { cloneChildren, isString } from '@react-fabric/utilities';
7
+ import { Icon, CoreIcons, Tooltip, Button, cloneChildren } from '@react-fabric/core';
8
+ import { isString } from '@react-fabric/utilities';
9
9
  import classNames from 'classnames';
10
10
  import { useMemo, useCallback, useImperativeHandle, cloneElement } from 'react';
11
11
  import { useFormContext, useFieldArray } from 'react-hook-form';
@@ -16,17 +16,18 @@ import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
16
16
  import { CSS } from '@dnd-kit/utilities';
17
17
  import { jsx, jsxs } from 'react/jsx-runtime';
18
18
 
19
- var _excluded = ["name", "children", "addLabel", "fixedList", "focusName", "onAdd", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems"];
19
+ var _excluded = ["name", "children", "addLabel", "fixedList", "focusName", "buttonPosition", "onAdd", "arrayRef", "enableSorting", "disabled", "readOnly", "minItems", "maxItems"];
20
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; }
21
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; }
22
22
  var ArrayInput = function ArrayInput(_ref) {
23
- var _error$values$label, _error$values, _error$values2;
24
23
  var name = _ref.name,
25
24
  children = _ref.children,
26
25
  addLabel = _ref.addLabel,
27
26
  fixedList = _ref.fixedList,
28
27
  _ref$focusName = _ref.focusName,
29
28
  focusName = _ref$focusName === void 0 ? "" : _ref$focusName,
29
+ _ref$buttonPosition = _ref.buttonPosition,
30
+ buttonPosition = _ref$buttonPosition === void 0 ? "bottom" : _ref$buttonPosition,
30
31
  onAdd = _ref.onAdd,
31
32
  arrayRef = _ref.arrayRef,
32
33
  enableSorting = _ref.enableSorting,
@@ -36,6 +37,8 @@ var ArrayInput = function ArrayInput(_ref) {
36
37
  readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly,
37
38
  _ref$minItems = _ref.minItems,
38
39
  minItems = _ref$minItems === void 0 ? 0 : _ref$minItems,
40
+ _ref$maxItems = _ref.maxItems,
41
+ maxItems = _ref$maxItems === void 0 ? Number.MAX_SAFE_INTEGER : _ref$maxItems,
39
42
  rest = _objectWithoutProperties(_ref, _excluded);
40
43
  var _useTranslation = useTranslation("form"),
41
44
  t = _useTranslation.t;
@@ -127,9 +130,32 @@ var ArrayInput = function ArrayInput(_ref) {
127
130
  }, [enableSorting]);
128
131
  // @ts-expect-error ignore
129
132
  SortableItem.displayName = "SortableItem";
133
+ var addButton = useMemo(function () {
134
+ var _error$values$label, _error$values, _error$values2;
135
+ return /*#__PURE__*/jsx("div", {
136
+ className: "flex justify-end",
137
+ children: /*#__PURE__*/jsx(Tooltip, {
138
+ color: "danger",
139
+ content: isString(error) ? "".concat(error) : t(error === null || error === void 0 ? void 0 : error.key, error !== null && error !== void 0 && error.values ? _objectSpread(_objectSpread({}, error === null || error === void 0 ? void 0 : error.values), {}, {
140
+ label: t((_error$values$label = (_error$values = error.values) === null || _error$values === void 0 ? void 0 : _error$values.label) !== null && _error$values$label !== void 0 ? _error$values$label : "form:badkey", (_error$values2 = error.values) === null || _error$values2 === void 0 ? void 0 : _error$values2.path)
141
+ }) : {}),
142
+ children: /*#__PURE__*/jsx(Button, {
143
+ "aria-label": "Add item",
144
+ icon: CoreIcons.insert,
145
+ onClick: function onClick() {
146
+ return handleAdd(onAdd === null || onAdd === void 0 ? void 0 : onAdd());
147
+ },
148
+ "data-invalid": !!error,
149
+ disabled: !!disabled || readOnly || fields.length < maxItems,
150
+ className: classNames(classes.addButton, "me-10"),
151
+ children: addLabel !== null && addLabel !== void 0 ? addLabel : t("addArray")
152
+ })
153
+ })
154
+ });
155
+ }, [error, fields, handleAdd, disabled, readOnly, addLabel, maxItems]);
130
156
  return /*#__PURE__*/jsxs("div", {
131
157
  className: classes.arrayInput,
132
- children: [/*#__PURE__*/jsx(FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
158
+ children: [!fixedList && onAdd && buttonPosition !== "bottom" && addButton, /*#__PURE__*/jsx(FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
133
159
  children: /*#__PURE__*/jsx(Wrapper, {
134
160
  children: fields.map(function (item, index) {
135
161
  return /*#__PURE__*/jsxs(SortableItem, {
@@ -163,26 +189,7 @@ var ArrayInput = function ArrayInput(_ref) {
163
189
  }, item.id);
164
190
  })
165
191
  })
166
- })), !fixedList && onAdd && /*#__PURE__*/jsx("div", {
167
- className: "flex justify-end",
168
- children: /*#__PURE__*/jsx(Tooltip, {
169
- color: "danger",
170
- content: isString(error) ? "".concat(error) : t(error === null || error === void 0 ? void 0 : error.key, error !== null && error !== void 0 && error.values ? _objectSpread(_objectSpread({}, error === null || error === void 0 ? void 0 : error.values), {}, {
171
- label: t((_error$values$label = (_error$values = error.values) === null || _error$values === void 0 ? void 0 : _error$values.label) !== null && _error$values$label !== void 0 ? _error$values$label : "form:badkey", (_error$values2 = error.values) === null || _error$values2 === void 0 ? void 0 : _error$values2.path)
172
- }) : {}),
173
- children: /*#__PURE__*/jsx(Button, {
174
- "aria-label": "Add item",
175
- icon: CoreIcons.insert,
176
- onClick: function onClick() {
177
- return handleAdd(onAdd());
178
- },
179
- "data-invalid": !!error,
180
- disabled: !!disabled || readOnly,
181
- className: classNames(classes.addButton, "me-10"),
182
- children: addLabel !== null && addLabel !== void 0 ? addLabel : t("addArray")
183
- })
184
- })
185
- })]
192
+ })), !fixedList && onAdd && buttonPosition !== "top" && addButton]
186
193
  });
187
194
  };
188
195
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
5
- import { cloneChildren } from '@react-fabric/utilities';
5
+ import { cloneChildren } from '@react-fabric/core';
6
6
  import classNames from 'classnames';
7
7
  import { cloneElement } from 'react';
8
8
  import classes from '../internal/Field.module.css';
@@ -2,7 +2,7 @@
2
2
 
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
5
- import { cloneChildren } from '@react-fabric/utilities';
5
+ import { cloneChildren } from '@react-fabric/core';
6
6
  import { cloneElement } from 'react';
7
7
  import { FieldWrapper } from '../internal/FieldWrapper.js';
8
8
  import { jsx } from 'react/jsx-runtime';
@@ -34,7 +34,7 @@ var Options = function Options(_ref) {
34
34
  i18nKey: "form:select.emptyList"
35
35
  })
36
36
  })), items.map(function (item, index) {
37
- var _item$labelProperty;
37
+ var _item$value, _item$labelProperty;
38
38
  if (item.___group___) return /*#__PURE__*/jsx("p", {
39
39
  className: "px-2 py-1 text-muted text-xs sticky -top-px z-2 bg-base border-t",
40
40
  children: item.label
@@ -51,7 +51,7 @@ var Options = function Options(_ref) {
51
51
  children: /*#__PURE__*/jsx(Trans, {
52
52
  i18nKey: "form:select.createOption",
53
53
  values: {
54
- query: item.value
54
+ query: (_item$value = item.value) !== null && _item$value !== void 0 ? _item$value : item
55
55
  },
56
56
  components: [/*#__PURE__*/jsx("strong", {
57
57
  children: "query"
@@ -140,6 +140,9 @@ var Select = function Select(_ref) {
140
140
  return false;
141
141
  } else if (state.query) {
142
142
  handleQuery("");
143
+ evt.preventDefault();
144
+ evt.stopPropagation();
145
+ return false;
143
146
  } else {
144
147
  onEnterPressed === null || onEnterPressed === void 0 || onEnterPressed(evt);
145
148
  }
@@ -140,7 +140,7 @@ var useSelect = function useSelect(_ref) {
140
140
  // add new item if allowCreate
141
141
  if (allowCreate && action.query) _newState.items.push({
142
142
  ___create___: true,
143
- value: createOption(action.query)
143
+ value: action.query
144
144
  });
145
145
  Object.entries(grouped).forEach(function (_ref2) {
146
146
  var _newState$items;
@@ -212,7 +212,7 @@ var useSelect = function useSelect(_ref) {
212
212
  var newOption = (allowCreate || autoComplete) && item ? createOption(item) : undefined;
213
213
  var hasValue = options.find(function (opt) {
214
214
  var _opt$valueProperty2;
215
- return ((_opt$valueProperty2 = opt[valueProperty]) !== null && _opt$valueProperty2 !== void 0 ? _opt$valueProperty2 : opt) === deferred;
215
+ return ((_opt$valueProperty2 = opt[valueProperty]) !== null && _opt$valueProperty2 !== void 0 ? _opt$valueProperty2 : opt) === item;
216
216
  });
217
217
  if (!hasValue && newOption) {
218
218
  optionsRef.current.push(newOption);
@@ -32,6 +32,10 @@ export interface ArrayInputProps {
32
32
  * minimum required length
33
33
  */
34
34
  minItems?: number;
35
+ /**
36
+ * maximum length
37
+ */
38
+ maxItems?: number;
35
39
  /**
36
40
  * field name to focus on add
37
41
  */
@@ -48,6 +52,7 @@ export interface ArrayInputProps {
48
52
  * add item button label
49
53
  */
50
54
  addLabel?: string;
55
+ buttonPosition?: "top" | "bottom" | "both";
51
56
  /**
52
57
  * fixed length list
53
58
  */
@@ -73,4 +78,4 @@ export interface ArrayInputProps {
73
78
  */
74
79
  labelWidth?: string;
75
80
  }
76
- export declare const ArrayInput: ({ name, children, addLabel, fixedList, focusName, onAdd, arrayRef, enableSorting, disabled, readOnly, minItems, ...rest }: ArrayInputProps) => import("react/jsx-runtime").JSX.Element;
81
+ export declare const ArrayInput: ({ name, children, addLabel, fixedList, focusName, buttonPosition, onAdd, arrayRef, enableSorting, disabled, readOnly, minItems, maxItems, ...rest }: ArrayInputProps) => 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.22",
3
+ "version": "1.0.0-beta.24",
4
4
  "description": "RUF: Form package",
5
5
  "author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
6
6
  "license": "MIT",
@@ -39,8 +39,8 @@
39
39
  "@dnd-kit/utilities": "^3.2.2",
40
40
  "@floating-ui/react": "^0.26.24",
41
41
  "@hookform/resolvers": "^3.9.0",
42
- "@react-fabric/core": "^1.0.0-beta.22",
43
- "@react-fabric/utilities": "^1.0.0-beta.22",
42
+ "@react-fabric/core": "^1.0.0-beta.24",
43
+ "@react-fabric/utilities": "^1.0.0-beta.24",
44
44
  "classnames": "^2.5.1",
45
45
  "color": "^4.2.3",
46
46
  "react-color": "^2.19.3",
@@ -60,5 +60,5 @@
60
60
  "node": ">=18.12.0",
61
61
  "npm": ">=8.19.0"
62
62
  },
63
- "gitHead": "71904746bcfbbb6b4ee39c5fc7a00c8f4a18a052"
63
+ "gitHead": "ccdec75c17dcc549e7a0cad3fd1fda2001c5f990"
64
64
  }
@@ -23,8 +23,14 @@
23
23
 
24
24
  import { DndContext, type DragEndEvent } from "@dnd-kit/core";
25
25
  import { SortableContext, useSortable } from "@dnd-kit/sortable";
26
- import { Button, CoreIcons, Icon, Tooltip } from "@react-fabric/core";
27
- import { cloneChildren, isString } from "@react-fabric/utilities";
26
+ import {
27
+ Button,
28
+ cloneChildren,
29
+ CoreIcons,
30
+ Icon,
31
+ Tooltip,
32
+ } from "@react-fabric/core";
33
+ import { isString } from "@react-fabric/utilities";
28
34
  import classNames from "classnames";
29
35
  import {
30
36
  cloneElement,
@@ -76,6 +82,10 @@ export interface ArrayInputProps {
76
82
  * minimum required length
77
83
  */
78
84
  minItems?: number;
85
+ /**
86
+ * maximum length
87
+ */
88
+ maxItems?: number;
79
89
  /**
80
90
  * field name to focus on add
81
91
  */
@@ -91,6 +101,7 @@ export interface ArrayInputProps {
91
101
  * add item button label
92
102
  */
93
103
  addLabel?: string;
104
+ buttonPosition?: "top" | "bottom" | "both";
94
105
  /**
95
106
  * fixed length list
96
107
  */
@@ -124,12 +135,14 @@ export const ArrayInput = ({
124
135
  addLabel,
125
136
  fixedList,
126
137
  focusName = "",
138
+ buttonPosition = "bottom",
127
139
  onAdd,
128
140
  arrayRef,
129
141
  enableSorting,
130
142
  disabled = false,
131
143
  readOnly = false,
132
144
  minItems = 0,
145
+ maxItems = Number.MAX_SAFE_INTEGER,
133
146
  ...rest
134
147
  }: ArrayInputProps) => {
135
148
  const { t } = useTranslation("form");
@@ -239,8 +252,47 @@ export const ArrayInput = ({
239
252
  // @ts-expect-error ignore
240
253
  SortableItem.displayName = "SortableItem";
241
254
 
255
+ const addButton = useMemo(
256
+ () => (
257
+ <div className="flex justify-end">
258
+ <Tooltip
259
+ color="danger"
260
+ content={
261
+ isString(error)
262
+ ? `${error}`
263
+ : (t(
264
+ error?.key,
265
+ error?.values
266
+ ? {
267
+ ...error?.values,
268
+ label: t(
269
+ error.values?.label ?? "form:badkey",
270
+ error.values?.path,
271
+ ),
272
+ }
273
+ : {},
274
+ ) as string)
275
+ }
276
+ >
277
+ <Button
278
+ aria-label="Add item"
279
+ icon={CoreIcons.insert}
280
+ onClick={() => handleAdd(onAdd?.())}
281
+ data-invalid={!!error}
282
+ disabled={!!disabled || readOnly || fields.length < maxItems}
283
+ className={classNames(classes.addButton, "me-10")}
284
+ >
285
+ {addLabel ?? t("addArray")}
286
+ </Button>
287
+ </Tooltip>
288
+ </div>
289
+ ),
290
+ [error, fields, handleAdd, disabled, readOnly, addLabel, maxItems],
291
+ );
292
+
242
293
  return (
243
294
  <div className={classes.arrayInput}>
295
+ {!fixedList && onAdd && buttonPosition !== "bottom" && addButton}
244
296
  <FieldWrapper {...rest}>
245
297
  <Wrapper>
246
298
  {fields.map((item, index) => (
@@ -291,40 +343,7 @@ export const ArrayInput = ({
291
343
  ))}
292
344
  </Wrapper>
293
345
  </FieldWrapper>
294
- {!fixedList && onAdd && (
295
- <div className="flex justify-end">
296
- <Tooltip
297
- color="danger"
298
- content={
299
- isString(error)
300
- ? `${error}`
301
- : (t(
302
- error?.key,
303
- error?.values
304
- ? {
305
- ...error?.values,
306
- label: t(
307
- error.values?.label ?? "form:badkey",
308
- error.values?.path,
309
- ),
310
- }
311
- : {},
312
- ) as string)
313
- }
314
- >
315
- <Button
316
- aria-label="Add item"
317
- icon={CoreIcons.insert}
318
- onClick={() => handleAdd(onAdd())}
319
- data-invalid={!!error}
320
- disabled={!!disabled || readOnly}
321
- className={classNames(classes.addButton, "me-10")}
322
- >
323
- {addLabel ?? t("addArray")}
324
- </Button>
325
- </Tooltip>
326
- </div>
327
- )}
346
+ {!fixedList && onAdd && buttonPosition !== "top" && addButton}
328
347
  </div>
329
348
  );
330
349
  };
@@ -21,11 +21,11 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
+ import { cloneChildren } from "@react-fabric/core";
24
25
  import {
25
26
  type ChildrenProp,
26
27
  type CssProp,
27
28
  } from "@react-fabric/core/dist/types/types";
28
- import { cloneChildren } from "@react-fabric/utilities";
29
29
  import classNames from "classnames";
30
30
  import { cloneElement } from "react";
31
31
  import classes from "../internal/Field.module.css";
@@ -21,11 +21,11 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
+ import { cloneChildren } from "@react-fabric/core";
24
25
  import {
25
26
  type ChildrenProp,
26
27
  type CssProp,
27
28
  } from "@react-fabric/core/dist/types/types";
28
- import { cloneChildren } from "@react-fabric/utilities";
29
29
  import { cloneElement } from "react";
30
30
  import { FieldWrapper } from "../internal/FieldWrapper";
31
31
  import { type Radio } from "./Radio";
@@ -93,7 +93,7 @@ export const Options = ({
93
93
  >
94
94
  <Trans
95
95
  i18nKey="form:select.createOption"
96
- values={{ query: item.value }}
96
+ values={{ query: item.value ?? item }}
97
97
  components={[<strong key="t0">query</strong>]}
98
98
  />
99
99
  </div>
@@ -172,6 +172,9 @@ export const Select = <T extends AnyObject = string>({
172
172
  return false;
173
173
  } else if (state.query) {
174
174
  handleQuery("");
175
+ evt.preventDefault();
176
+ evt.stopPropagation();
177
+ return false;
175
178
  } else {
176
179
  onEnterPressed?.(evt);
177
180
  }
@@ -232,7 +232,7 @@ export const useSelect = ({
232
232
  if (allowCreate && action.query)
233
233
  newState.items.push({
234
234
  ___create___: true,
235
- value: createOption(action.query),
235
+ value: action.query,
236
236
  });
237
237
  Object.entries(grouped).forEach(([key, list]) => {
238
238
  if (key) {
@@ -297,7 +297,7 @@ export const useSelect = ({
297
297
  ? createOption(item)
298
298
  : undefined;
299
299
  const hasValue = options.find(
300
- (opt: AnyObject) => (opt[valueProperty] ?? opt) === deferred,
300
+ (opt: AnyObject) => (opt[valueProperty] ?? opt) === item,
301
301
  );
302
302
  if (!hasValue && newOption) {
303
303
  optionsRef.current.push(newOption);