@react-fabric/form 1.0.0-beta.35 → 1.0.0-beta.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/{src/input/ArrayInput.module.css → css/_arrayInput.css} +8 -8
  2. package/{src/input/ColorPicker.module.css → css/_colorPicker.css} +13 -13
  3. package/{src/internal/Field.module.css → css/_field.css} +17 -17
  4. package/{src/input/File.module.css → css/_file.css} +7 -7
  5. package/css/styles.css +27 -0
  6. package/dist/cjs/builder/FileField.js +35 -23
  7. package/dist/cjs/builder/SchemaEditor.js +6 -1
  8. package/dist/cjs/builder/components/SchemaArrayForm.js +1 -2
  9. package/dist/cjs/builder/components/SchemaField.js +5 -3
  10. package/dist/cjs/input/ArrayInput.js +3 -4
  11. package/dist/cjs/input/AvatarInput.js +1 -1
  12. package/dist/cjs/input/Checkbox.js +1 -1
  13. package/dist/cjs/input/ColorInput.js +1 -1
  14. package/dist/cjs/input/ColorPicker.js +1 -2
  15. package/dist/cjs/input/Field.js +1 -2
  16. package/dist/cjs/input/File.js +1 -2
  17. package/dist/cjs/input/Radio.js +1 -1
  18. package/dist/cjs/internal/ErrorIcon.js +1 -1
  19. package/dist/cjs/internal/FieldWrapper.js +1 -2
  20. package/dist/cjs/internal/InputWrapper.js +4 -5
  21. package/dist/cjs/select/AutoComplete.js +1 -1
  22. package/dist/cjs/select/Select.js +1 -1
  23. package/dist/esm/builder/FileField.js +37 -25
  24. package/dist/esm/builder/SchemaEditor.js +6 -1
  25. package/dist/esm/builder/components/SchemaArrayForm.js +1 -2
  26. package/dist/esm/builder/components/SchemaField.js +5 -3
  27. package/dist/esm/input/ArrayInput.js +3 -4
  28. package/dist/esm/input/AvatarInput.js +1 -1
  29. package/dist/esm/input/Checkbox.js +1 -1
  30. package/dist/esm/input/ColorInput.js +1 -1
  31. package/dist/esm/input/ColorPicker.js +1 -2
  32. package/dist/esm/input/Field.js +1 -2
  33. package/dist/esm/input/File.js +1 -2
  34. package/dist/esm/input/Radio.js +1 -1
  35. package/dist/esm/internal/ErrorIcon.js +1 -1
  36. package/dist/esm/internal/FieldWrapper.js +1 -2
  37. package/dist/esm/internal/InputWrapper.js +4 -5
  38. package/dist/esm/select/AutoComplete.js +1 -1
  39. package/dist/esm/select/Select.js +1 -1
  40. package/dist/types/builder/FileField.d.ts +3 -1
  41. package/dist/types/builder/SchemaEditor.d.ts +1 -1
  42. package/dist/types/types/schema.d.ts +2 -1
  43. package/package.json +16 -5
  44. package/src/builder/FileField.tsx +48 -23
  45. package/src/builder/SchemaEditor.tsx +6 -1
  46. package/src/builder/components/SchemaArrayForm.tsx +2 -2
  47. package/src/builder/components/SchemaField.tsx +40 -37
  48. package/src/input/ArrayInput.tsx +3 -4
  49. package/src/input/AvatarInput.tsx +1 -1
  50. package/src/input/Checkbox.tsx +1 -1
  51. package/src/input/ColorInput.tsx +1 -1
  52. package/src/input/ColorPicker.tsx +1 -2
  53. package/src/input/Field.tsx +1 -2
  54. package/src/input/File.tsx +2 -5
  55. package/src/input/Radio.tsx +1 -1
  56. package/src/internal/ErrorIcon.tsx +1 -1
  57. package/src/internal/FieldWrapper.tsx +1 -2
  58. package/src/internal/InputWrapper.tsx +6 -7
  59. package/src/select/AutoComplete.tsx +1 -1
  60. package/src/select/Select.tsx +1 -1
  61. package/src/types/schema.ts +2 -1
  62. package/dist/cjs/input/ArrayInput.module.css +0 -1
  63. package/dist/cjs/input/ColorPicker.module.css +0 -1
  64. package/dist/cjs/input/File.module.css +0 -1
  65. package/dist/cjs/internal/Field.module.css +0 -1
  66. package/dist/esm/input/ArrayInput.module.css +0 -1
  67. package/dist/esm/input/ColorPicker.module.css +0 -1
  68. package/dist/esm/input/File.module.css +0 -1
  69. package/dist/esm/internal/Field.module.css +0 -1
@@ -4,26 +4,32 @@ import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
5
5
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
6
6
  import _regeneratorRuntime from '@babel/runtime/regenerator';
7
- import { Button, Icon, ProgressBar } from '@react-fabric/core';
8
- import { FileUtil, Format } from '@react-fabric/utilities';
7
+ import { Tooltip, Button, Icon, ProgressBar } from '@react-fabric/core';
8
+ import { isString, FileUtil, Format } from '@react-fabric/utilities';
9
9
  import { Fragment } from 'react';
10
+ import { useTranslation } from 'react-i18next';
10
11
  import { useFileUploader } from '../hooks/useFileUploader.js';
11
12
  import { Field } from '../input/Field.js';
12
13
  import { HiddenInput } from '../input/Hidden.js';
13
14
  import { jsxs, jsx } from 'react/jsx-runtime';
14
15
 
15
- var _excluded = ["uploadHandler", "inline", "label", "accept", "value", "fileUrl", "multiple"];
16
+ var _excluded = ["uploadHandler", "inline", "label", "accept", "value", "fileUrl", "multiple", "invalid", "error"];
16
17
  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; }
17
18
  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; }
18
19
  var FileField = function FileField(_ref) {
20
+ var _error$values$label, _error$values, _error$values2;
19
21
  var uploadHandler = _ref.uploadHandler,
20
22
  inline = _ref.inline,
21
23
  label = _ref.label,
22
24
  accept = _ref.accept,
23
25
  value = _ref.value;
24
26
  _ref.fileUrl;
25
- var multiple = _ref.multiple,
27
+ var multiple = _ref.multiple;
28
+ _ref.invalid;
29
+ var error = _ref.error,
26
30
  rest = _objectWithoutProperties(_ref, _excluded);
31
+ var _useTranslation = useTranslation(),
32
+ t = _useTranslation.t;
27
33
  var _useFileUploader = useFileUploader( /*#__PURE__*/function () {
28
34
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(data, config) {
29
35
  return _regeneratorRuntime.wrap(function _callee$(_context) {
@@ -49,32 +55,38 @@ var FileField = function FileField(_ref) {
49
55
  upload = _useFileUploader.upload,
50
56
  remove = _useFileUploader.remove;
51
57
  return /*#__PURE__*/jsxs(Fragment, {
52
- children: [/*#__PURE__*/jsxs(Field, {
58
+ children: [/*#__PURE__*/jsx(Field, {
53
59
  plain: true,
54
60
  inline: inline,
55
61
  label: label,
56
- className: "inline-block",
57
- children: [/*#__PURE__*/jsx(HiddenInput, _objectSpread({
62
+ children: /*#__PURE__*/jsx(HiddenInput, _objectSpread({
58
63
  hiddenValue: multiple ? list : list === null || list === void 0 ? void 0 : list[0]
59
- }, rest)), /*#__PURE__*/jsx("span", {
60
- children: /*#__PURE__*/jsx(Button, {
61
- badge: pending > 0 ? "".concat(pending) : undefined,
62
- "data-ref": "filebtn",
63
- children: /*#__PURE__*/jsxs(Fragment, {
64
- children: [/*#__PURE__*/jsx("span", {
65
- children: "Add file"
66
- }), /*#__PURE__*/jsx("input", {
67
- type: "file",
68
- accept: accept,
69
- multiple: multiple,
70
- className: "absolute inset-0 opacity-0 z-5",
71
- onChange: function onChange(e) {
72
- return [upload(e.target.files), e.target.value = ""];
73
- }
74
- })]
75
- })
64
+ }, rest))
65
+ }), /*#__PURE__*/jsx(Tooltip, {
66
+ color: "danger-200",
67
+ content: isString(error) ? "".concat(error) : error && t(error === null || error === void 0 ? void 0 : error.key, error.values ? _objectSpread(_objectSpread({}, error === null || error === void 0 ? void 0 : error.values), {}, {
68
+ 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)
69
+ }) : {}),
70
+ disabled: !error,
71
+ children: /*#__PURE__*/jsx(Button, {
72
+ badge: pending > 0 ? "".concat(pending) : undefined,
73
+ color: error ? "danger" : undefined,
74
+ variant: error ? "soft" : undefined,
75
+ "data-ref": "filebtn",
76
+ children: /*#__PURE__*/jsxs(Fragment, {
77
+ children: [/*#__PURE__*/jsx("span", {
78
+ children: "Add file"
79
+ }), /*#__PURE__*/jsx("input", {
80
+ type: "file",
81
+ accept: accept,
82
+ multiple: multiple,
83
+ className: "absolute inset-0 opacity-0 z-5",
84
+ onChange: function onChange(e) {
85
+ return [upload(e.target.files), e.target.value = ""];
86
+ }
87
+ })]
76
88
  })
77
- })]
89
+ })
78
90
  }), /*#__PURE__*/jsx("br", {}), /*#__PURE__*/jsx("div", {
79
91
  className: "bg-alternate",
80
92
  children: files.map(function (file, idx) {
@@ -38,11 +38,15 @@ var SchemaEditor = function SchemaEditor(_ref) {
38
38
  _ref$optionLists = _ref.optionLists,
39
39
  optionLists = _ref$optionLists === void 0 ? EMPTY_ARRAY : _ref$optionLists,
40
40
  children = _ref.children,
41
+ onSubmit = _ref.onSubmit,
41
42
  onChange = _ref.onChange;
42
43
  var formRef = useRef(null);
43
44
  var handleChange = useCallback(function (model) {
44
45
  onChange === null || onChange === void 0 || onChange(model.schema);
45
46
  }, []);
47
+ var handleSubmit = useCallback(function (model) {
48
+ onSubmit === null || onSubmit === void 0 || onSubmit(model.schema);
49
+ }, []);
46
50
  useEffect(function () {
47
51
  var _formRef$current;
48
52
  (_formRef$current = formRef.current) === null || _formRef$current === void 0 || _formRef$current.setValues({
@@ -51,7 +55,8 @@ var SchemaEditor = function SchemaEditor(_ref) {
51
55
  }, [schemaDef]);
52
56
  return /*#__PURE__*/jsxs(Form, {
53
57
  formRef: formRef,
54
- onSubmit: handleChange,
58
+ onChange: handleChange,
59
+ onSubmit: handleSubmit,
55
60
  children: [/*#__PURE__*/jsx(SchemaArrayForm, {
56
61
  dynamic: dynamic,
57
62
  optionLists: optionLists,
@@ -29,10 +29,9 @@ var SchemaArrayForm = function SchemaArrayForm(_ref) {
29
29
  fields = _useFieldArray.fields,
30
30
  append = _useFieldArray.append,
31
31
  remove = _useFieldArray.remove,
32
- update = _useFieldArray.update,
33
32
  move = _useFieldArray.move;
34
33
  var handleTypeChange = useCallback(function (index, val) {
35
- update(index, val);
34
+ form.setValue("schema.".concat(index), val);
36
35
  }, []);
37
36
  var handleRemove = useCallback(function (index) {
38
37
  remove(index);
@@ -130,7 +130,7 @@ var SchemaField = function SchemaField(_ref) {
130
130
  var modelRef = getModel();
131
131
  var reset = {
132
132
  datatype: type,
133
- id: field,
133
+ id: id,
134
134
  label: modelRef.label,
135
135
  defaultValue: modelRef.defaultValue,
136
136
  required: modelRef.required,
@@ -161,7 +161,7 @@ var SchemaField = function SchemaField(_ref) {
161
161
  onTypeChange(reset);
162
162
  setType(type);
163
163
  }
164
- }, []);
164
+ }, [id]);
165
165
  return /*#__PURE__*/jsx(SortableItem, {
166
166
  id: fieldId,
167
167
  className: "flex flex-nowrap gap-1 group/field",
@@ -244,7 +244,9 @@ var SchemaField = function SchemaField(_ref) {
244
244
  icon: CoreIcons.list,
245
245
  "aria-label": "Custom options",
246
246
  onClick: function onClick() {
247
- void openOptionModal();
247
+ void openOptionModal({
248
+ title: "".concat(id, " Options")
249
+ });
248
250
  }
249
251
  })]
250
252
  }), OptionModal]
@@ -11,7 +11,6 @@ import { useMemo, useCallback, useImperativeHandle, cloneElement } from 'react';
11
11
  import { useFormContext, useFieldArray } from 'react-hook-form';
12
12
  import { useTranslation } from 'react-i18next';
13
13
  import { FieldWrapper } from '../internal/FieldWrapper.js';
14
- import classes from './ArrayInput.module.css';
15
14
  import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
16
15
  import { CSS } from '@dnd-kit/utilities';
17
16
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -135,7 +134,7 @@ var ArrayInput = function ArrayInput(_ref) {
135
134
  return /*#__PURE__*/jsx("div", {
136
135
  className: "flex justify-end",
137
136
  children: /*#__PURE__*/jsx(Tooltip, {
138
- color: "danger",
137
+ color: "danger-200",
139
138
  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
139
  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
140
  }) : {}),
@@ -148,14 +147,14 @@ var ArrayInput = function ArrayInput(_ref) {
148
147
  },
149
148
  "data-invalid": !!error,
150
149
  disabled: !!disabled || readOnly || fields.length > maxItems,
151
- className: classNames(classes.addButton, "me-10"),
150
+ className: classNames("fabric-addButton", "me-10"),
152
151
  children: addLabel !== null && addLabel !== void 0 ? addLabel : t("addArray")
153
152
  })
154
153
  })
155
154
  });
156
155
  }, [error, fields, handleAdd, disabled, readOnly, addLabel, maxItems]);
157
156
  return /*#__PURE__*/jsxs("div", {
158
- className: classes.arrayInput,
157
+ className: "fabric-arrayInput",
159
158
  children: [/*#__PURE__*/jsx(FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
160
159
  appendLabel: /*#__PURE__*/jsx("div", {
161
160
  className: "-me-2",
@@ -80,7 +80,7 @@ var AvatarInput = function AvatarInput(_ref) {
80
80
  size: size,
81
81
  avatar: base64
82
82
  }), /*#__PURE__*/jsxs("div", {
83
- className: "absolute inset-x-0 bottom-0 cursor-pointer bg-opacity-20 hover:bg-opacity-50 bg-black text-white text-xs text-center py-1",
83
+ className: "absolute inset-x-0 bottom-0 cursor-pointer bg-black/20 hover:bg-black/50 text-white text-xs text-center py-1",
84
84
  children: [/*#__PURE__*/jsx("span", {
85
85
  children: "Edit"
86
86
  }), /*#__PURE__*/jsx("input", {
@@ -67,7 +67,7 @@ var Checkbox = function Checkbox(_ref) {
67
67
  checked: actualValue,
68
68
  onChange: handleChange
69
69
  }, rest)), /*#__PURE__*/jsx(Icon, {
70
- className: classNames("p-0.5", actualValue && icon && !iconChecked && "bg-primary-500 text-white"),
70
+ className: classNames("p-0.5", actualValue && icon && !iconChecked && "bg-primary-500 text-white!"),
71
71
  size: "1.25em",
72
72
  color: invalid ? "danger" : "primary",
73
73
  icon: actualValue ? iconOn : iconOff
@@ -77,7 +77,7 @@ var ColorInput = function ColorInput(_ref) {
77
77
  getReferenceProps = _useInteractions.getReferenceProps,
78
78
  getFloatingProps = _useInteractions.getFloatingProps;
79
79
  return /*#__PURE__*/jsxs("div", {
80
- className: classNames("flex-content min-h-[1.5em] min-w-[3.5em] self-stretch flex items-center outline-tint-200 rounded", !disabled && "bg-base", !noOutline && "bg-[var(--fabric-input)] outline overflow-hidden"),
80
+ className: classNames("flex-content min-h-[1.5em] min-w-[3.5em] self-stretch flex items-center outline-tint-200 rounded", !disabled && "bg-base", !noOutline && "bg-(--fabric-input) outline overflow-hidden"),
81
81
  children: [decorateStart && /*#__PURE__*/jsx("div", {
82
82
  className: classNames("text-muted leading-none flex-content", isString(decorateStart) && "px-2"),
83
83
  children: decorateStart
@@ -5,7 +5,6 @@ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
5
5
  import Color from 'color';
6
6
  import { memo, useState, useDeferredValue, useEffect, useCallback, startTransition } from 'react';
7
7
  import { SketchPicker } from 'react-color';
8
- import classes from './ColorPicker.module.css';
9
8
  import { jsx } from 'react/jsx-runtime';
10
9
 
11
10
  var _excluded = ["a"],
@@ -37,7 +36,7 @@ var ColorPicker = /*#__PURE__*/memo(function (_ref) {
37
36
  }, [onChange]);
38
37
  return /*#__PURE__*/jsx(SketchPicker, {
39
38
  width: "16rem",
40
- className: classes.colorPicker,
39
+ className: "fabric-colorPicker",
41
40
  styles: {
42
41
  "default": {
43
42
  hue: {
@@ -5,7 +5,6 @@ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProper
5
5
  import { cloneChildren } from '@react-fabric/core';
6
6
  import classNames from 'classnames';
7
7
  import { cloneElement } from 'react';
8
- import classes from '../internal/Field.module.css';
9
8
  import { FieldWrapper } from '../internal/FieldWrapper.js';
10
9
  import { jsx } from 'react/jsx-runtime';
11
10
 
@@ -20,7 +19,7 @@ var Field = function Field(_ref) {
20
19
  rest = _objectWithoutProperties(_ref, _excluded);
21
20
  return /*#__PURE__*/jsx(FieldWrapper, _objectSpread(_objectSpread({}, rest), {}, {
22
21
  children: /*#__PURE__*/jsx("div", {
23
- className: classNames(classes.fieldGroup, !plain && !noOutline && "outline", !plain && "bg-base", plain && "flex-wrap", "flex-1 rounded", !vertical && "flex"),
22
+ className: classNames("fabric-fieldGroup", !plain && !noOutline && "outline", !plain && "bg-base", plain && "flex-wrap", "flex-1 rounded", !vertical && "flex"),
24
23
  children: cloneChildren(children, function (child) {
25
24
  return /*#__PURE__*/cloneElement(child, {
26
25
  "data-inner": true
@@ -9,7 +9,6 @@ import classNames from 'classnames';
9
9
  import { useRef, useState, useDeferredValue, useMemo, useEffect, useCallback, Fragment } from 'react';
10
10
  import { InputWrapper } from '../internal/InputWrapper.js';
11
11
  import { handleEnter } from '../utils/eventHandlers.js';
12
- import classes from './File.module.css';
13
12
  import { jsx, jsxs } from 'react/jsx-runtime';
14
13
 
15
14
  var _excluded = ["ref", "value", "invalid", "readOnly", "disabled", "required", "placeholder", "autoFocus", "error", "name", "accept", "showList", "multiple", "onChange", "onEnterPressed"];
@@ -139,7 +138,7 @@ var FileInput = function FileInput(_ref) {
139
138
  })
140
139
  }, rest), {}, {
141
140
  children: /*#__PURE__*/jsx("input", {
142
- className: classNames("appearance-none bg-transparent py-1 px-2 flex-1 border-none outline-none ring-0", classes.fileInput, isArray(actualValue) && (actualValue === null || actualValue === void 0 ? void 0 : actualValue.length) && "text-[var(--fabric-bg)]"),
141
+ className: classNames("appearance-none bg-transparent py-1 px-2 flex-1 border-none outline-none ring-0", "fabric-fileInput", isArray(actualValue) && (actualValue === null || actualValue === void 0 ? void 0 : actualValue.length) && "text-(--fabric-bg)"),
143
142
  "aria-invalid": invalid,
144
143
  "aria-disabled": disabled,
145
144
  "aria-readonly": readOnly,
@@ -51,7 +51,7 @@ var Radio = function Radio(_ref) {
51
51
  autoComplete: "off",
52
52
  onChange: handleChange
53
53
  }, rest)), /*#__PURE__*/jsx(Icon, {
54
- className: classNames("p-0.5 hidden peer-checked:inline-block", icon && !iconChecked && "bg-primary-500 text-white"),
54
+ className: classNames("p-0.5 hidden peer-checked:inline-block", icon && !iconChecked && "bg-primary-500 text-white!"),
55
55
  color: invalid ? "danger" : "primary",
56
56
  size: "1.25em",
57
57
  icon: iconOn
@@ -20,7 +20,7 @@ var ErrorIcon = function ErrorIcon(_ref) {
20
20
  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)
21
21
  }) : {}),
22
22
  placement: "bottom",
23
- color: "danger",
23
+ color: "danger-200",
24
24
  children: /*#__PURE__*/jsx(Icon, {
25
25
  className: "flex-content first:ms-2 self-center",
26
26
  color: "danger",
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import classNames from 'classnames';
4
- import classes from './Field.module.css';
5
4
  import { jsxs, jsx } from 'react/jsx-runtime';
6
5
 
7
6
  /*
@@ -42,7 +41,7 @@ var FieldWrapper = function FieldWrapper(_ref) {
42
41
  className = _ref.className,
43
42
  isInner = _ref["data-inner"];
44
43
  return /*#__PURE__*/jsxs("div", {
45
- className: classNames(classes.fieldWrapper, className, inline ? "flex flex-nowrap gap-1" : "block"),
44
+ className: classNames("fabric-fieldWrapper", className, inline ? "flex flex-nowrap gap-1" : "block"),
46
45
  "data-ref": "fieldWrapper",
47
46
  style: {
48
47
  width: width,
@@ -9,7 +9,6 @@ import classNames from 'classnames';
9
9
  import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
10
10
  import { Fragment, jsxs, jsx } from 'react/jsx-runtime';
11
11
  import { ErrorIcon } from './ErrorIcon.js';
12
- import classes from './Field.module.css';
13
12
  import { FieldWrapper } from './FieldWrapper.js';
14
13
 
15
14
  var _excluded = ["invalid", "error", "allowClear", "showClear", "decorateStart", "decorateEnd", "decorateEndShowWhenEmpty", "decorateEndHideWhenEmpty", "children", "onClear", "noOutline", "noBorder", "textarea", "textareaExpandable", "data-inner", "data-open", "floatingExpand", "wrapperRef", "width"];
@@ -69,13 +68,13 @@ var InputWrapper = function InputWrapper(_ref) {
69
68
  var el = /*#__PURE__*/jsxs("div", {
70
69
  role: "none",
71
70
  ref: wrapperRef,
72
- className: classNames(classes.inputWrapper, invalid && classes.invalidWrapper, !noOutline && !noBorder && "bg-[var(--fabric-input)] outline overflow-hidden", "flex flex-nowrap items-center flex-1", textarea ? "rounded-capped group" : "rounded", isExpanded ? "fixed inset-4 z-[99]" : floatingExpand ? "absolute inset-x-0" : "relative", !noOutline && "after:absolute after:bottom-0 after:h-px after:bg-primary-500 after:mx-auto"),
71
+ className: classNames("fabric-inputWrapper", invalid && "fabric-invalidWrapper", !noOutline && !noBorder && "bg-(--fabric-input) outline overflow-hidden", "flex flex-nowrap items-center flex-1", textarea ? "rounded-capped group" : "rounded", isExpanded ? "fixed inset-4 z-[99]" : floatingExpand ? "absolute inset-x-0" : "relative", !noOutline && "after:absolute after:bottom-0 after:h-px after:bg-primary-500 after:mx-auto"),
73
72
  onKeyDown: function onKeyDown(e) {
74
73
  return e.key === "Escape" && isExpanded && (setExpanded(false), e.stopPropagation());
75
74
  },
76
75
  children: [decorateStart && /*#__PURE__*/jsx("div", {
77
76
  onClickCapture: doFocus,
78
- className: classNames(classes.decorate, "text-muted leading-none flex-content", isString(decorateStart) && "px-1"),
77
+ className: classNames("fabric-decorate", "text-muted leading-none flex-content", isString(decorateStart) && "px-1"),
79
78
  children: decorateStart
80
79
  }), /*#__PURE__*/jsx(ErrorIcon, {
81
80
  invalid: invalid,
@@ -83,10 +82,10 @@ var InputWrapper = function InputWrapper(_ref) {
83
82
  }), children, allowClear && showClear && /*#__PURE__*/jsx(Icon, {
84
83
  icon: CoreIcons.close,
85
84
  onClick: handleClear,
86
- className: classNames("text-tint-500 hover:text-tint-700 p-1 z-1 flex-content", classes.inputClear, textarea && "self-start mt-1 me-1")
85
+ className: classNames("text-tint-500 hover:text-tint-700 p-1 z-1 flex-content", "fabric-inputClear", textarea && "self-start mt-1 me-1")
87
86
  }), decorateEnd && /*#__PURE__*/jsx("div", {
88
87
  onClickCapture: doFocus,
89
- className: classNames(classes.decorate, "text-muted leading-none flex-content", isString(decorateEnd) && "px-1", decorateEndHideWhenEmpty && "peer-placeholder-shown:hidden", decorateEndShowWhenEmpty && "hidden peer-placeholder-shown:inline-block"),
88
+ className: classNames("fabric-decorate", "text-muted leading-none flex-content", isString(decorateEnd) && "px-1", decorateEndHideWhenEmpty && "peer-placeholder-shown:hidden", decorateEndShowWhenEmpty && "hidden peer-placeholder-shown:inline-block"),
90
89
  children: decorateEnd
91
90
  }), textareaExpandable && /*#__PURE__*/jsx(Icon, {
92
91
  onClick: function onClick() {
@@ -243,7 +243,7 @@ var AutoComplete = function AutoComplete(_ref) {
243
243
  visuallyHiddenDismiss: true,
244
244
  children: /*#__PURE__*/jsx(Options, _objectSpread(_objectSpread({
245
245
  ref: refs.setFloating,
246
- className: "outline shadow-lg max-h-[40vh] z-[var(--z-popover)]",
246
+ className: "outline shadow-lg max-h-[40vh] z-(--z-popover)",
247
247
  style: _objectSpread({
248
248
  width: (_refs$reference$curre = refs.reference.current) === null || _refs$reference$curre === void 0 ? void 0 : _refs$reference$curre.getBoundingClientRect().width
249
249
  }, floatingStyles)
@@ -262,7 +262,7 @@ var Select = function Select(_ref) {
262
262
  visuallyHiddenDismiss: true,
263
263
  children: /*#__PURE__*/jsx(Options, _objectSpread(_objectSpread({
264
264
  ref: refs.setFloating,
265
- className: "outline shadow-lg max-h-[40vh] z-[var(--z-popover)]",
265
+ className: "outline shadow-lg max-h-[40vh] z-(--z-popover)",
266
266
  style: _objectSpread({
267
267
  width: (_refs$reference$curre = refs.reference.current) === null || _refs$reference$curre === void 0 ? void 0 : _refs$reference$curre.getBoundingClientRect().width
268
268
  }, floatingStyles)
@@ -1,8 +1,10 @@
1
1
  import { type UploadHandler } from "../hooks/useFileUploader";
2
2
  import { type FileSchema, type ValueType } from "../types/schema";
3
- export declare const FileField: ({ uploadHandler, inline, label, accept, value, fileUrl, multiple, ...rest }: Partial<FileSchema & ValueType> & {
3
+ export declare const FileField: ({ uploadHandler, inline, label, accept, value, fileUrl, multiple, invalid, error, ...rest }: Partial<FileSchema & ValueType> & {
4
4
  value?: AnyObject;
5
5
  inline?: boolean;
6
+ invalid?: boolean;
7
+ error?: AnyObject;
6
8
  fileUrl?: (path: string) => string;
7
9
  uploadHandler: UploadHandler;
8
10
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { type SchemaEditorProps } from "../types/schema";
2
- export declare const SchemaEditor: ({ schemaDef, dynamic, acceptableTypes, optionLists, children, onChange, }: SchemaEditorProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const SchemaEditor: ({ schemaDef, dynamic, acceptableTypes, optionLists, children, onSubmit, onChange, }: SchemaEditorProps) => import("react/jsx-runtime").JSX.Element;
@@ -99,6 +99,7 @@ export interface SchemaEditorProps {
99
99
  * footer actions
100
100
  */
101
101
  children?: Elements<JSX.Element> | Array<Elements<JSX.Element>>;
102
- onChange: (schema: FormSchema) => void;
102
+ onChange?: (schema: FormSchema) => void;
103
+ onSubmit?: (schema: FormSchema) => void;
103
104
  }
104
105
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-fabric/form",
3
- "version": "1.0.0-beta.35",
3
+ "version": "1.0.0-beta.37",
4
4
  "description": "RUF: Form package",
5
5
  "author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
6
6
  "license": "MIT",
@@ -11,12 +11,23 @@
11
11
  "types": "dist/types/index.d.ts",
12
12
  "directories": {
13
13
  "src": "src",
14
+ "styles": "css",
14
15
  "test": "tests"
15
16
  },
16
17
  "files": [
18
+ "css",
17
19
  "src",
18
20
  "dist"
19
21
  ],
22
+ "exports": {
23
+ ".": {
24
+ "default": "./dist/esm/index.js",
25
+ "import": "./dist/esm/index.js",
26
+ "require": "./dist/cjs/index.js",
27
+ "types": "./dist/types/index.d.ts"
28
+ },
29
+ "./styles": "./css/styles.css"
30
+ },
20
31
  "publishConfig": {
21
32
  "access": "public",
22
33
  "registry": "https://registry.npmjs.org/"
@@ -39,9 +50,9 @@
39
50
  "@dnd-kit/utilities": "^3.2.2",
40
51
  "@floating-ui/react": "^0.26.24",
41
52
  "@hookform/resolvers": "^3.9.0",
42
- "@react-fabric/core": "^1.0.0-beta.35",
43
- "@react-fabric/date": "^1.0.0-beta.35",
44
- "@react-fabric/utilities": "^1.0.0-beta.35",
53
+ "@react-fabric/core": "^1.0.0-beta.37",
54
+ "@react-fabric/date": "^1.0.0-beta.37",
55
+ "@react-fabric/utilities": "^1.0.0-beta.37",
45
56
  "classnames": "^2.5.1",
46
57
  "color": "^4.2.3",
47
58
  "react-color": "^2.19.3",
@@ -61,5 +72,5 @@
61
72
  "node": ">=18.12.0",
62
73
  "npm": ">=8.19.0"
63
74
  },
64
- "gitHead": "4a5cb87557f8c7c88cac937e3bd71fd6eeb07113"
75
+ "gitHead": "9b737229bf24ebe986540ee2c4b8904ebc4a5a9b"
65
76
  }
@@ -21,9 +21,10 @@
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 { Button, Icon, ProgressBar } from "@react-fabric/core";
25
- import { FileUtil, Format } from "@react-fabric/utilities";
24
+ import { Button, Icon, ProgressBar, Tooltip } from "@react-fabric/core";
25
+ import { FileUtil, Format, isString } from "@react-fabric/utilities";
26
26
  import { Fragment } from "react";
27
+ import { useTranslation } from "react-i18next";
27
28
  import { useFileUploader, type UploadHandler } from "../hooks/useFileUploader";
28
29
  import { Field } from "../input/Field";
29
30
  import { HiddenInput } from "../input/Hidden";
@@ -37,13 +38,18 @@ export const FileField = ({
37
38
  value,
38
39
  fileUrl,
39
40
  multiple,
41
+ invalid,
42
+ error,
40
43
  ...rest
41
44
  }: Partial<FileSchema & ValueType> & {
42
45
  value?: AnyObject;
43
46
  inline?: boolean;
47
+ invalid?: boolean;
48
+ error?: AnyObject;
44
49
  fileUrl?: (path: string) => string;
45
50
  uploadHandler: UploadHandler;
46
51
  }) => {
52
+ const { t } = useTranslation();
47
53
  const { pending, files, list, upload, remove } = useFileUploader(
48
54
  async (data, config) => await uploadHandler?.(data, config),
49
55
  value,
@@ -52,29 +58,48 @@ export const FileField = ({
52
58
 
53
59
  return (
54
60
  <Fragment>
55
- <Field plain inline={inline} label={label} className="inline-block">
61
+ <Field plain inline={inline} label={label}>
56
62
  <HiddenInput hiddenValue={multiple ? list : list?.[0]} {...rest} />
57
- <span>
58
- <Button
59
- badge={pending > 0 ? `${pending}` : undefined}
60
- data-ref="filebtn"
61
- >
62
- <Fragment>
63
- <span>Add file</span>
64
- <input
65
- type="file"
66
- accept={accept}
67
- multiple={multiple}
68
- className="absolute inset-0 opacity-0 z-5"
69
- onChange={(e) => [
70
- upload(e.target.files),
71
- (e.target.value = ""),
72
- ]}
73
- />
74
- </Fragment>
75
- </Button>
76
- </span>
77
63
  </Field>
64
+ <Tooltip
65
+ color="danger-200"
66
+ content={
67
+ isString(error)
68
+ ? `${error}`
69
+ : error &&
70
+ (t(
71
+ error?.key,
72
+ error.values
73
+ ? {
74
+ ...error?.values,
75
+ label: t(
76
+ error.values?.label ?? "form:badkey",
77
+ error.values?.path,
78
+ ),
79
+ }
80
+ : {},
81
+ ) as string)
82
+ }
83
+ disabled={!error}
84
+ >
85
+ <Button
86
+ badge={pending > 0 ? `${pending}` : undefined}
87
+ color={error ? "danger" : undefined}
88
+ variant={error ? "soft" : undefined}
89
+ data-ref="filebtn"
90
+ >
91
+ <Fragment>
92
+ <span>Add file</span>
93
+ <input
94
+ type="file"
95
+ accept={accept}
96
+ multiple={multiple}
97
+ className="absolute inset-0 opacity-0 z-5"
98
+ onChange={(e) => [upload(e.target.files), (e.target.value = "")]}
99
+ />
100
+ </Fragment>
101
+ </Button>
102
+ </Tooltip>
78
103
  <br />
79
104
  <div className="bg-alternate">
80
105
  {files.map((file, idx) => (
@@ -38,6 +38,7 @@ export const SchemaEditor = ({
38
38
  acceptableTypes,
39
39
  optionLists = EMPTY_ARRAY,
40
40
  children,
41
+ onSubmit,
41
42
  onChange,
42
43
  }: SchemaEditorProps) => {
43
44
  const formRef = useRef<FormRef<{ schema: FormSchema }>>(null);
@@ -46,12 +47,16 @@ export const SchemaEditor = ({
46
47
  onChange?.(model.schema);
47
48
  }, []);
48
49
 
50
+ const handleSubmit = useCallback((model: { schema: FormSchema }) => {
51
+ onSubmit?.(model.schema);
52
+ }, []);
53
+
49
54
  useEffect(() => {
50
55
  formRef.current?.setValues({ schema: schemaDef });
51
56
  }, [schemaDef]);
52
57
 
53
58
  return (
54
- <Form formRef={formRef} onSubmit={handleChange}>
59
+ <Form formRef={formRef} onChange={handleChange} onSubmit={handleSubmit}>
55
60
  <SchemaArrayForm
56
61
  dynamic={dynamic}
57
62
  optionLists={optionLists}
@@ -45,13 +45,13 @@ export const SchemaArrayForm = ({
45
45
  }: Partial<SchemaEditorProps>) => {
46
46
  const form = useFormContext();
47
47
  const [defaultOpen, setDefaultOpen] = useState(true);
48
- const { fields, append, remove, update, move } = useFieldArray({
48
+ const { fields, append, remove, move } = useFieldArray({
49
49
  name: "schema",
50
50
  control: form.control,
51
51
  });
52
52
 
53
53
  const handleTypeChange = useCallback((index: number, val: KeyValue) => {
54
- update(index, val);
54
+ form.setValue(`schema.${index}`, val);
55
55
  }, []);
56
56
 
57
57
  const handleRemove = useCallback((index: number) => {