@react-fabric/form 1.0.0-beta.47 → 1.0.0-beta.48

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 (65) hide show
  1. package/dist/cjs/builder/FormField.js +7 -1
  2. package/dist/cjs/builder/components/SchemaField.js +2 -1
  3. package/dist/cjs/input/AvatarInput.js +8 -7
  4. package/dist/cjs/input/DateInput.js +2 -4
  5. package/dist/cjs/input/File.js +1 -3
  6. package/dist/cjs/input/Input.js +2 -4
  7. package/dist/cjs/input/Number.js +1 -3
  8. package/dist/cjs/input/Password.js +1 -3
  9. package/dist/cjs/input/Search.js +3 -5
  10. package/dist/cjs/input/Switch.js +2 -1
  11. package/dist/cjs/input/Textarea.js +4 -3
  12. package/dist/cjs/internal/FieldWrapper.js +6 -0
  13. package/dist/cjs/select/AutoComplete.js +3 -2
  14. package/dist/cjs/select/List.js +3 -1
  15. package/dist/cjs/select/Select.js +3 -1
  16. package/dist/cjs/select/useSelect.js +2 -1
  17. package/dist/cjs/types/schema.js +1 -0
  18. package/dist/cjs/utils/eventHandlers.js +11 -5
  19. package/dist/esm/builder/FormField.js +7 -1
  20. package/dist/esm/builder/components/SchemaField.js +2 -1
  21. package/dist/esm/input/AvatarInput.js +8 -7
  22. package/dist/esm/input/DateInput.js +3 -5
  23. package/dist/esm/input/File.js +3 -5
  24. package/dist/esm/input/Input.js +4 -6
  25. package/dist/esm/input/Number.js +3 -5
  26. package/dist/esm/input/Password.js +3 -5
  27. package/dist/esm/input/Search.js +5 -7
  28. package/dist/esm/input/Switch.js +2 -1
  29. package/dist/esm/input/Textarea.js +5 -4
  30. package/dist/esm/internal/FieldWrapper.js +6 -0
  31. package/dist/esm/select/AutoComplete.js +3 -2
  32. package/dist/esm/select/List.js +3 -1
  33. package/dist/esm/select/Select.js +3 -1
  34. package/dist/esm/select/useSelect.js +2 -1
  35. package/dist/esm/types/schema.js +1 -0
  36. package/dist/esm/utils/eventHandlers.js +11 -5
  37. package/dist/types/form/Form.d.ts +5 -1
  38. package/dist/types/input/AvatarInput.d.ts +6 -3
  39. package/dist/types/internal/FieldWrapper.d.ts +1 -1
  40. package/dist/types/select/List.d.ts +1 -1
  41. package/dist/types/select/Select.d.ts +1 -1
  42. package/dist/types/select/useSelect.d.ts +2 -1
  43. package/dist/types/types/index.d.ts +4 -0
  44. package/dist/types/types/schema.d.ts +2 -2
  45. package/dist/types/utils/eventHandlers.d.ts +1 -1
  46. package/package.json +9 -9
  47. package/src/builder/FormField.tsx +8 -1
  48. package/src/builder/components/SchemaField.tsx +2 -1
  49. package/src/form/Form.tsx +7 -1
  50. package/src/input/AvatarInput.tsx +11 -7
  51. package/src/input/DateInput.tsx +3 -6
  52. package/src/input/File.tsx +2 -6
  53. package/src/input/Input.tsx +3 -7
  54. package/src/input/Number.tsx +2 -6
  55. package/src/input/Password.tsx +2 -6
  56. package/src/input/Search.tsx +4 -8
  57. package/src/input/Textarea.tsx +6 -4
  58. package/src/internal/FieldWrapper.tsx +4 -0
  59. package/src/select/AutoComplete.tsx +1 -0
  60. package/src/select/List.tsx +2 -0
  61. package/src/select/Select.tsx +2 -0
  62. package/src/select/useSelect.tsx +4 -1
  63. package/src/types/index.ts +4 -0
  64. package/src/types/schema.ts +2 -2
  65. package/src/utils/eventHandlers.ts +9 -3
@@ -6,7 +6,8 @@ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProper
6
6
  import classNames from 'classnames';
7
7
  import { useState, useDeferredValue, useEffect, useCallback, Fragment } from 'react';
8
8
  import { ErrorIcon } from '../internal/ErrorIcon.js';
9
- import '@react-fabric/utilities';
9
+ import '@floating-ui/react';
10
+ import '@react-fabric/core';
10
11
  import { getBgClass, getColor, getColorClass } from '../utils/getColor.js';
11
12
  import { jsxs, jsx } from 'react/jsx-runtime';
12
13
 
@@ -5,7 +5,7 @@ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
5
5
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
6
6
  import { useState, useDeferredValue, useRef, useEffect, useCallback } from 'react';
7
7
  import { InputWrapper } from '../internal/InputWrapper.js';
8
- import { handleEnter } from '../utils/eventHandlers.js';
8
+ import { useHandleEnter } from '../utils/eventHandlers.js';
9
9
  import '@react-fabric/utilities';
10
10
  import { jsx } from 'react/jsx-runtime';
11
11
 
@@ -60,6 +60,9 @@ var Textarea = function Textarea(_ref) {
60
60
  setFixedRows(rows);
61
61
  }
62
62
  }, [actualValue, variableRows, rows, maxRows]);
63
+ var handleEnterPressed = useHandleEnter(onEnterPressed, {
64
+ preventDefault: !!onEnterPressed
65
+ });
63
66
  return /*#__PURE__*/jsx(InputWrapper, _objectSpread(_objectSpread({
64
67
  showClear: !!actualValue && !disabled && !readOnly,
65
68
  onClear: handleChange,
@@ -89,9 +92,7 @@ var Textarea = function Textarea(_ref) {
89
92
  onBlur: onBlur,
90
93
  onFocus: onFocus,
91
94
  onChange: handleChange,
92
- onKeyDown: handleEnter(onEnterPressed, {
93
- preventDefault: !!onEnterPressed
94
- })
95
+ onKeyDown: handleEnterPressed
95
96
  })
96
97
  }));
97
98
  };
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import classNames from 'classnames';
4
+ import { ErrorIcon } from './ErrorIcon.js';
4
5
  import { jsxs, jsx } from 'react/jsx-runtime';
5
6
 
6
7
  /*
@@ -39,6 +40,8 @@ var FieldWrapper = function FieldWrapper(_ref) {
39
40
  children = _ref.children,
40
41
  listing = _ref.listing,
41
42
  className = _ref.className,
43
+ invalid = _ref.invalid,
44
+ error = _ref.error,
42
45
  isInner = _ref["data-inner"];
43
46
  return /*#__PURE__*/jsxs("div", {
44
47
  className: classNames("fabric-fieldWrapper", className, inline ? "flex flex-nowrap gap-1" : "block"),
@@ -63,6 +66,9 @@ var FieldWrapper = function FieldWrapper(_ref) {
63
66
  }), required && /*#__PURE__*/jsx("span", {
64
67
  className: "text-danger-500 select-none flex-content text-[10px]",
65
68
  children: "\u273D"
69
+ }), /*#__PURE__*/jsx(ErrorIcon, {
70
+ invalid: invalid,
71
+ error: error
66
72
  }), /*#__PURE__*/jsx("div", {
67
73
  className: "flex-1"
68
74
  }), appendLabel && /*#__PURE__*/jsx("span", {
@@ -17,8 +17,8 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
17
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; }
18
18
  var AutoComplete = function AutoComplete(_ref) {
19
19
  var _refs$reference$curre;
20
- _ref.ref;
21
- var name = _ref.name,
20
+ var ref = _ref.ref,
21
+ name = _ref.name,
22
22
  value = _ref.value,
23
23
  invalid = _ref.invalid,
24
24
  readOnly = _ref.readOnly,
@@ -220,6 +220,7 @@ var AutoComplete = function AutoComplete(_ref) {
220
220
  "data-testid": name,
221
221
  name: name,
222
222
  size: 1,
223
+ ref: ref,
223
224
  onInput: onInput,
224
225
  autoFocus: autoFocus,
225
226
  rows: !multiple && expandOnEdit && state.open ? 5 : 1,
@@ -13,7 +13,7 @@ import { Options } from './Options.js';
13
13
  import { useSelect } from './useSelect.js';
14
14
  import { jsx, jsxs } from 'react/jsx-runtime';
15
15
 
16
- var _excluded = ["ref", "name", "value", "readOnly", "disabled", "required", "placeholder", "autoFocus", "options", "height", "groupProperty", "labelProperty", "valueProperty", "multiple", "allowCreate", "searchable", "createOption", "matcher", "renderer", "onQuery", "onChange", "onSelect", "onEnterPressed", "emptyDisplay", "invalid", "error", "allowClear", "decorateStart", "decorateEnd", "data-inner", "data-hide-selected"];
16
+ var _excluded = ["ref", "name", "value", "readOnly", "disabled", "required", "placeholder", "autoFocus", "options", "height", "groupProperty", "labelProperty", "valueProperty", "sortProperty", "multiple", "allowCreate", "searchable", "createOption", "matcher", "renderer", "onQuery", "onChange", "onSelect", "onEnterPressed", "emptyDisplay", "invalid", "error", "allowClear", "decorateStart", "decorateEnd", "data-inner", "data-hide-selected"];
17
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; }
18
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; }
19
19
  var List = function List(_ref) {
@@ -31,6 +31,7 @@ var List = function List(_ref) {
31
31
  groupProperty = _ref.groupProperty,
32
32
  labelProperty = _ref.labelProperty,
33
33
  valueProperty = _ref.valueProperty,
34
+ sortProperty = _ref.sortProperty,
34
35
  multiple = _ref.multiple,
35
36
  allowCreate = _ref.allowCreate,
36
37
  searchable = _ref.searchable,
@@ -63,6 +64,7 @@ var List = function List(_ref) {
63
64
  groupProperty: groupProperty,
64
65
  labelProperty: labelProperty,
65
66
  valueProperty: valueProperty,
67
+ sortProperty: sortProperty,
66
68
  allowCreate: allowCreate,
67
69
  createOption: createOption,
68
70
  matcher: matcher,
@@ -12,7 +12,7 @@ import { Options } from './Options.js';
12
12
  import { useSelect } from './useSelect.js';
13
13
  import { jsx, jsxs } from 'react/jsx-runtime';
14
14
 
15
- var _excluded = ["ref", "name", "value", "invalid", "readOnly", "disabled", "required", "placeholder", "autoFocus", "error", "options", "defaultOpen", "hideHandle", "groupProperty", "labelProperty", "valueProperty", "multiple", "searchable", "allowCreate", "emptyDisplay", "createOption", "matcher", "renderer", "onQuery", "onChange", "onSelect", "onEnterPressed"];
15
+ var _excluded = ["ref", "name", "value", "invalid", "readOnly", "disabled", "required", "placeholder", "autoFocus", "error", "options", "defaultOpen", "hideHandle", "groupProperty", "labelProperty", "valueProperty", "sortProperty", "multiple", "searchable", "allowCreate", "emptyDisplay", "createOption", "matcher", "renderer", "onQuery", "onChange", "onSelect", "onEnterPressed"];
16
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; }
17
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; }
18
18
  var Select = function Select(_ref) {
@@ -35,6 +35,7 @@ var Select = function Select(_ref) {
35
35
  labelProperty = _ref$labelProperty === void 0 ? "label" : _ref$labelProperty,
36
36
  _ref$valueProperty = _ref.valueProperty,
37
37
  valueProperty = _ref$valueProperty === void 0 ? "id" : _ref$valueProperty,
38
+ sortProperty = _ref.sortProperty,
38
39
  multiple = _ref.multiple,
39
40
  searchable = _ref.searchable,
40
41
  allowCreate = _ref.allowCreate,
@@ -55,6 +56,7 @@ var Select = function Select(_ref) {
55
56
  groupProperty: groupProperty,
56
57
  labelProperty: labelProperty,
57
58
  valueProperty: valueProperty,
59
+ sortProperty: sortProperty,
58
60
  allowCreate: allowCreate,
59
61
  createOption: createOption,
60
62
  matcher: matcher,
@@ -27,6 +27,7 @@ var useSelect = function useSelect(_ref) {
27
27
  valueProperty = _ref$valueProperty === void 0 ? "id" : _ref$valueProperty,
28
28
  _ref$labelProperty = _ref.labelProperty,
29
29
  labelProperty = _ref$labelProperty === void 0 ? "label" : _ref$labelProperty,
30
+ sortProperty = _ref.sortProperty,
30
31
  _ref$createOption = _ref.createOption,
31
32
  createOption = _ref$createOption === void 0 ? makeOption : _ref$createOption,
32
33
  matcher = _ref.matcher,
@@ -135,7 +136,7 @@ var useSelect = function useSelect(_ref) {
135
136
  if (autoComplete && action.query !== undefined) {
136
137
  optionList = dedupe([action.query].concat(_toConsumableArray(optionList)));
137
138
  }
138
- optionList = optionList.sort(compareValues("asc", labelProperty));
139
+ if (sortProperty) optionList = optionList.sort(compareValues("asc", sortProperty));
139
140
  var grouped = groupBy(optionList, groupProperty, "");
140
141
  if (action.open) _newState.open = true;
141
142
  _newState.items = [];
@@ -28,6 +28,7 @@ var DATA_TYPES = /*#__PURE__*/function (DATA_TYPES) {
28
28
  DATA_TYPES["COLOR"] = "color";
29
29
  DATA_TYPES["BOOL"] = "bool";
30
30
  DATA_TYPES["DATE"] = "date";
31
+ DATA_TYPES["DATETIME"] = "datetime";
31
32
  DATA_TYPES["STRING"] = "string";
32
33
  DATA_TYPES["NUMBER"] = "number";
33
34
  DATA_TYPES["RANGE"] = "range";
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { debounce } from '@react-fabric/utilities';
3
+ import { useFloatingTree } from '@floating-ui/react';
4
+ import { useDebounce } from '@react-fabric/core';
4
5
 
5
6
  /*
6
7
  * React Fabric
@@ -26,16 +27,21 @@ import { debounce } from '@react-fabric/utilities';
26
27
  */
27
28
 
28
29
  /** ***************** common handler for enter press *******************/
29
- var handleEnter = function handleEnter(callback) {
30
+ var useHandleEnter = function useHandleEnter(callback) {
30
31
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
31
32
  _ref$stopPropagation = _ref.stopPropagation,
32
33
  stopPropagation = _ref$stopPropagation === void 0 ? false : _ref$stopPropagation,
33
34
  _ref$preventDefault = _ref.preventDefault,
34
35
  preventDefault = _ref$preventDefault === void 0 ? false : _ref$preventDefault;
35
- var cbHandle = debounce(callback !== null && callback !== void 0 ? callback : function () {
36
+ var cbHandle = useDebounce(callback !== null && callback !== void 0 ? callback : function () {
36
37
  return undefined;
37
- }, 100);
38
+ }, [callback], 100);
39
+ var tree = useFloatingTree();
38
40
  return function (e) {
41
+ // prevent propagation of event if input within dropdown (work around for floating-ui typeahead)
42
+ if (tree && e.key !== "Escape") {
43
+ e === null || e === void 0 || e.stopPropagation();
44
+ }
39
45
  if (!e.shiftKey && !e.altKey && !e.metaKey && e.key === "Enter" && callback) {
40
46
  if (stopPropagation) e === null || e === void 0 || e.stopPropagation();
41
47
  cbHandle(e);
@@ -47,4 +53,4 @@ var handleEnter = function handleEnter(callback) {
47
53
  };
48
54
  };
49
55
 
50
- export { handleEnter };
56
+ export { useHandleEnter };
@@ -1,6 +1,9 @@
1
1
  import { type yup } from "@react-fabric/utilities";
2
2
  import { type PropsWithChildren, type Ref } from "react";
3
3
  import { type FormState } from "react-hook-form";
4
+ type NestedKeyOf<T extends object> = {
5
+ [K in keyof T & (string | number)]: T[K] extends object ? `${K}` | `${K}.${NestedKeyOf<T[K]>}` : K;
6
+ }[keyof T & (string | number)];
4
7
  export interface FormRef<K extends KeyValue> {
5
8
  state: FormState<K>;
6
9
  reset: () => void;
@@ -8,7 +11,7 @@ export interface FormRef<K extends KeyValue> {
8
11
  submit: () => void;
9
12
  validate: () => Promise<boolean>;
10
13
  getValues: () => K;
11
- setValue: (key: keyof K, value: AnyObject) => void;
14
+ setValue: (key: NestedKeyOf<K>, value: AnyObject) => void;
12
15
  setValues: (values: K) => void;
13
16
  }
14
17
  export interface FormProps<K extends KeyValue = KeyValue> {
@@ -31,3 +34,4 @@ export interface FormProps<K extends KeyValue = KeyValue> {
31
34
  onSubmit?: (values: K) => void;
32
35
  }
33
36
  export declare const Form: <K extends KeyValue<any>>({ formRef, schema, children, defaultValues, onSubmit, onChange, ...rest }: PropsWithChildren<FormProps<K>>) => import("react/jsx-runtime").JSX.Element;
37
+ export {};
@@ -10,14 +10,17 @@ export interface Props extends RefProp {
10
10
  */
11
11
  value?: string;
12
12
  /**
13
- * avatar stream src
13
+ * avatar name
14
14
  */
15
- src?: string;
15
+ avatarName?: string;
16
16
  size?: string | number;
17
17
  /**
18
18
  * upload handler to store file in temp storage
19
19
  */
20
20
  uploadHandler: UploadHandler;
21
+ /**
22
+ * file stream path
23
+ */
21
24
  fileUrl?: (path: string) => string;
22
25
  /**
23
26
  * change handler
@@ -28,4 +31,4 @@ export interface Props extends RefProp {
28
31
  */
29
32
  onChange?: (path: string) => void;
30
33
  }
31
- export declare const AvatarInput: ({ src, size, fileUrl, uploadHandler, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
34
+ export declare const AvatarInput: ({ size, avatarName, value, fileUrl, uploadHandler, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- export declare const FieldWrapper: ({ label, appendLabel, width, labelWidth, inline, info, disabled, required, children, listing, className, "data-inner": isInner, }: KeyValue) => import("react/jsx-runtime").JSX.Element;
1
+ export declare const FieldWrapper: ({ label, appendLabel, width, labelWidth, inline, info, disabled, required, children, listing, className, invalid, error, "data-inner": isInner, }: KeyValue) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import { type SelectProps } from "../types";
2
- export declare const List: <T extends unknown = string>({ ref, name, value, readOnly, disabled, required, placeholder, autoFocus, options, height, groupProperty, labelProperty, valueProperty, multiple, allowCreate, searchable, createOption, matcher, renderer, onQuery, onChange, onSelect, onEnterPressed, emptyDisplay, invalid, error, allowClear, decorateStart, decorateEnd, "data-inner": isInner, "data-hide-selected": hideSelected, ...rest }: Omit<SelectProps<T>, "defaultOpen" | "hideHandle"> & {
2
+ export declare const List: <T extends unknown = string>({ ref, name, value, readOnly, disabled, required, placeholder, autoFocus, options, height, groupProperty, labelProperty, valueProperty, sortProperty, multiple, allowCreate, searchable, createOption, matcher, renderer, onQuery, onChange, onSelect, onEnterPressed, emptyDisplay, invalid, error, allowClear, decorateStart, decorateEnd, "data-inner": isInner, "data-hide-selected": hideSelected, ...rest }: Omit<SelectProps<T>, "defaultOpen" | "hideHandle"> & {
3
3
  height?: string | number;
4
4
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { type SelectProps } from "../types";
2
- export declare const Select: <T extends unknown = string>({ ref, name, value, invalid, readOnly, disabled, required, placeholder, autoFocus, error, options, defaultOpen, hideHandle, groupProperty, labelProperty, valueProperty, multiple, searchable, allowCreate, emptyDisplay, createOption, matcher, renderer, onQuery, onChange, onSelect, onEnterPressed, ...rest }: SelectProps<T>) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const Select: <T extends unknown = string>({ ref, name, value, invalid, readOnly, disabled, required, placeholder, autoFocus, error, options, defaultOpen, hideHandle, groupProperty, labelProperty, valueProperty, sortProperty, multiple, searchable, allowCreate, emptyDisplay, createOption, matcher, renderer, onQuery, onChange, onSelect, onEnterPressed, ...rest }: SelectProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -10,7 +10,7 @@ interface State {
10
10
  query?: string;
11
11
  items: AnyObject[];
12
12
  }
13
- export declare const useSelect: ({ options, value, defaultOpen, autoComplete, multiple, allowCreate, groupProperty, valueProperty, labelProperty, createOption, matcher, onQuery, onChange, onSelect, }: {
13
+ export declare const useSelect: ({ options, value, defaultOpen, autoComplete, multiple, allowCreate, groupProperty, valueProperty, labelProperty, sortProperty, createOption, matcher, onQuery, onChange, onSelect, }: {
14
14
  value?: AnyObject;
15
15
  options?: AnyObject[];
16
16
  multiple?: boolean;
@@ -19,6 +19,7 @@ export declare const useSelect: ({ options, value, defaultOpen, autoComplete, mu
19
19
  groupProperty?: AnyObject;
20
20
  valueProperty?: AnyObject;
21
21
  labelProperty?: AnyObject;
22
+ sortProperty?: AnyObject;
22
23
  autoComplete?: boolean;
23
24
  matcher?: (item: AnyObject, query: string) => boolean;
24
25
  createOption?: (query: string) => AnyObject;
@@ -118,6 +118,10 @@ export interface BaseSelectProps<T extends AnyObject = string> {
118
118
  * value property name
119
119
  */
120
120
  valueProperty?: keyof T;
121
+ /**
122
+ * value property name
123
+ */
124
+ sortProperty?: keyof T | true;
121
125
  /**
122
126
  * searchable list
123
127
  */
@@ -6,6 +6,7 @@ export declare enum DATA_TYPES {
6
6
  COLOR = "color",
7
7
  BOOL = "bool",
8
8
  DATE = "date",
9
+ DATETIME = "datetime",
9
10
  STRING = "string",
10
11
  NUMBER = "number",
11
12
  RANGE = "range",
@@ -51,8 +52,7 @@ export interface RangeSchema extends BaseSchema {
51
52
  step?: number;
52
53
  }
53
54
  export interface DateSchema extends BaseSchema {
54
- datatype: DATA_TYPES.DATE;
55
- type?: "date" | "datetime";
55
+ datatype: DATA_TYPES.DATE | DATA_TYPES.DATETIME;
56
56
  min?: DateLike;
57
57
  max?: DateLike;
58
58
  }
@@ -1,6 +1,6 @@
1
1
  import { type KeyboardEvent, type MouseEvent } from "react";
2
2
  /** ***************** common handler for enter press *******************/
3
- export declare const handleEnter: (callback?: (e: KeyboardEvent) => void, { stopPropagation, preventDefault, }?: {
3
+ export declare const useHandleEnter: (callback?: (e: KeyboardEvent) => void, { stopPropagation, preventDefault, }?: {
4
4
  stopPropagation?: boolean;
5
5
  preventDefault?: boolean;
6
6
  }) => (e: KeyboardEvent) => false | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-fabric/form",
3
- "version": "1.0.0-beta.47",
3
+ "version": "1.0.0-beta.48",
4
4
  "description": "RUF: Form package",
5
5
  "author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
6
6
  "license": "MIT",
@@ -35,15 +35,15 @@
35
35
  "watch": "npm-run-all -p watch:rollup watch:dts"
36
36
  },
37
37
  "dependencies": {
38
- "@dnd-kit/core": "^6.1.0",
39
- "@dnd-kit/modifiers": "^7.0.0",
40
- "@dnd-kit/sortable": "^8.0.0",
38
+ "@dnd-kit/core": "^6.3.1",
39
+ "@dnd-kit/modifiers": "^9.0.0",
40
+ "@dnd-kit/sortable": "^10.0.0",
41
41
  "@dnd-kit/utilities": "^3.2.2",
42
- "@floating-ui/react": "^0.26.24",
42
+ "@floating-ui/react": "^0.27.9",
43
43
  "@hookform/resolvers": "^3.9.0",
44
- "@react-fabric/core": "^1.0.0-beta.47",
45
- "@react-fabric/date": "^1.0.0-beta.47",
46
- "@react-fabric/utilities": "^1.0.0-beta.47",
44
+ "@react-fabric/core": "^1.0.0-beta.48",
45
+ "@react-fabric/date": "^1.0.0-beta.48",
46
+ "@react-fabric/utilities": "^1.0.0-beta.48",
47
47
  "classnames": "^2.5.1",
48
48
  "color": "^4.2.3",
49
49
  "react-color": "^2.19.3",
@@ -63,5 +63,5 @@
63
63
  "node": ">=18.12.0",
64
64
  "npm": ">=8.19.0"
65
65
  },
66
- "gitHead": "832a1bce055337127ba17c505731f419248cc15e"
66
+ "gitHead": "0b1001b4ae1ee67f8e1817d6395d1f3945321897"
67
67
  }
@@ -79,6 +79,7 @@ export const FormField = ({
79
79
  if (rest.datatype === DATA_TYPES.BOOL) return Switch;
80
80
  if (rest.datatype === DATA_TYPES.TEXT) return Textarea;
81
81
  if (rest.datatype === DATA_TYPES.DATE) return DateInput;
82
+ if (rest.datatype === DATA_TYPES.DATETIME) return DateInput;
82
83
  if (rest.datatype === DATA_TYPES.COLOR) return ColorInput;
83
84
  if (hasOptions) return Select;
84
85
 
@@ -104,7 +105,13 @@ export const FormField = ({
104
105
  return {
105
106
  min: rest.min,
106
107
  max: rest.max,
107
- type: rest.type,
108
+ type: "date",
109
+ };
110
+ if (rest.datatype === DATA_TYPES.DATETIME)
111
+ return {
112
+ min: rest.min,
113
+ max: rest.max,
114
+ type: "datetime",
108
115
  };
109
116
  if (rest.datatype === DATA_TYPES.TEXT) return { rows: 3 };
110
117
  if (rest.datatype === DATA_TYPES.COLOR) return { showPicker: true };
@@ -190,7 +190,8 @@ export const SchemaField = ({
190
190
  } as StringSchema);
191
191
  } else if (type === DATA_TYPES.DATE) {
192
192
  reset = Object.assign(reset, {
193
- type: "date",
193
+ min: modelRef.min,
194
+ max: modelRef.max,
194
195
  } as DateSchema);
195
196
  } else if (type === DATA_TYPES.NUMBER || type === DATA_TYPES.RANGE) {
196
197
  reset = Object.assign(reset, {
package/src/form/Form.tsx CHANGED
@@ -40,6 +40,12 @@ import {
40
40
  type FormState,
41
41
  } from "react-hook-form";
42
42
 
43
+ type NestedKeyOf<T extends object> = {
44
+ [K in keyof T & (string | number)]: T[K] extends object
45
+ ? `${K}` | `${K}.${NestedKeyOf<T[K]>}`
46
+ : K;
47
+ }[keyof T & (string | number)];
48
+
43
49
  export interface FormRef<K extends KeyValue> {
44
50
  state: FormState<K>;
45
51
  reset: () => void;
@@ -47,7 +53,7 @@ export interface FormRef<K extends KeyValue> {
47
53
  submit: () => void;
48
54
  validate: () => Promise<boolean>;
49
55
  getValues: () => K;
50
- setValue: (key: keyof K, value: AnyObject) => void;
56
+ setValue: (key: NestedKeyOf<K>, value: AnyObject) => void;
51
57
  setValues: (values: K) => void;
52
58
  }
53
59
 
@@ -37,14 +37,17 @@ export interface Props extends RefProp {
37
37
  */
38
38
  value?: string;
39
39
  /**
40
- * avatar stream src
40
+ * avatar name
41
41
  */
42
- src?: string;
42
+ avatarName?: string;
43
43
  size?: string | number;
44
44
  /**
45
45
  * upload handler to store file in temp storage
46
46
  */
47
47
  uploadHandler: UploadHandler;
48
+ /**
49
+ * file stream path
50
+ */
48
51
  fileUrl?: (path: string) => string;
49
52
  /**
50
53
  * change handler
@@ -57,15 +60,16 @@ export interface Props extends RefProp {
57
60
  }
58
61
 
59
62
  export const AvatarInput = ({
60
- src,
61
63
  size = "6rem",
64
+ avatarName,
65
+ value,
62
66
  fileUrl,
63
67
  uploadHandler,
64
68
  ...rest
65
69
  }: Props) => {
66
70
  const { files, list, upload, remove } = useFileUploader(
67
71
  async (data, config) => await uploadHandler?.(data, config),
68
- rest.value,
72
+ value,
69
73
  false,
70
74
  );
71
75
 
@@ -92,13 +96,13 @@ export const AvatarInput = ({
92
96
  }, [files, list]);
93
97
 
94
98
  useEffect(() => {
95
- src && setBase64(fileUrl?.(src) ?? src);
96
- }, [src]);
99
+ value && setBase64(fileUrl?.(value) ?? value);
100
+ }, [value]);
97
101
 
98
102
  return (
99
103
  <div className="flex flex-nowrap items-end">
100
104
  <div className="inline-block leading-none rounded-full relative outline overflow-hidden">
101
- <Avatar name="temp" size={size} avatar={base64} />
105
+ <Avatar name={avatarName ?? "temp"} size={size} avatar={base64} />
102
106
  <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">
103
107
  <span>Edit</span>
104
108
  <input
@@ -37,6 +37,7 @@ import {
37
37
  import { type RefProp } from "@react-fabric/core/dist/types/types";
38
38
  import { type DateLike, DatePanel, DateUtil } from "@react-fabric/date";
39
39
  import { mergeRefs } from "@react-fabric/utilities";
40
+ import classNames from "classnames";
40
41
  import {
41
42
  type ChangeEvent,
42
43
  startTransition,
@@ -49,8 +50,7 @@ import {
49
50
  } from "react";
50
51
  import { InputWrapper } from "../internal/InputWrapper";
51
52
  import { type InputProps } from "../types";
52
- import { handleEnter } from "../utils";
53
- import classNames from "classnames";
53
+ import { useHandleEnter } from "../utils";
54
54
 
55
55
  export interface DateProps
56
56
  extends InputProps<string>,
@@ -105,10 +105,7 @@ export const DateInput = ({
105
105
  setInputValue(deferred ? DateUtil.format(deferred, inputFormat) : "");
106
106
  }, [deferred, inputFormat]);
107
107
 
108
- const handleEnterPressed = useMemo(
109
- () => handleEnter(onEnterPressed),
110
- [onEnterPressed],
111
- );
108
+ const handleEnterPressed = useHandleEnter(onEnterPressed);
112
109
 
113
110
  const handleChange = useCallback(
114
111
  (e?: ChangeEvent<HTMLInputElement>) => {
@@ -36,14 +36,13 @@ import {
36
36
  useCallback,
37
37
  useDeferredValue,
38
38
  useEffect,
39
- useMemo,
40
39
  useRef,
41
40
  useState,
42
41
  type ChangeEvent,
43
42
  } from "react";
44
43
  import { InputWrapper } from "../internal/InputWrapper";
45
44
  import { type InputProps } from "../types";
46
- import { handleEnter } from "../utils";
45
+ import { useHandleEnter } from "../utils";
47
46
 
48
47
  export interface FileInputProps
49
48
  extends InputProps<AnyObject>,
@@ -100,10 +99,7 @@ export const FileInput = ({
100
99
  const [actualValue, setActualValue] = useState<File | File[] | null>();
101
100
  const deferred = useDeferredValue(value);
102
101
 
103
- const handleEnterPressed = useMemo(
104
- () => handleEnter(onEnterPressed),
105
- [onEnterPressed],
106
- );
102
+ const handleEnterPressed = useHandleEnter(onEnterPressed);
107
103
 
108
104
  useEffect(() => {
109
105
  setActualValue(deferred);
@@ -22,18 +22,17 @@
22
22
  */
23
23
 
24
24
  import { type RefProp } from "@react-fabric/core/dist/types/types";
25
+ import classNames from "classnames";
25
26
  import {
26
27
  useCallback,
27
28
  useDeferredValue,
28
29
  useEffect,
29
- useMemo,
30
30
  useState,
31
31
  type ChangeEvent,
32
32
  } from "react";
33
33
  import { InputWrapper } from "../internal/InputWrapper";
34
34
  import { type InputProps } from "../types";
35
- import { handleEnter } from "../utils";
36
- import classNames from "classnames";
35
+ import { useHandleEnter } from "../utils";
37
36
 
38
37
  export interface TextInputProps extends InputProps, RefProp<HTMLInputElement> {
39
38
  /**
@@ -64,10 +63,7 @@ export const Input = ({
64
63
  const [actualValue, setActualValue] = useState("");
65
64
  const deferred = useDeferredValue(value);
66
65
 
67
- const handleEnterPressed = useMemo(
68
- () => handleEnter(onEnterPressed),
69
- [onEnterPressed],
70
- );
66
+ const handleEnterPressed = useHandleEnter(onEnterPressed);
71
67
 
72
68
  useEffect(() => {
73
69
  setActualValue(deferred ?? "");
@@ -26,13 +26,12 @@ import {
26
26
  useCallback,
27
27
  useDeferredValue,
28
28
  useEffect,
29
- useMemo,
30
29
  useState,
31
30
  type ChangeEvent,
32
31
  } from "react";
33
32
  import { InputWrapper } from "../internal/InputWrapper";
34
33
  import { type InputProps } from "../types";
35
- import { handleEnter } from "../utils";
34
+ import { useHandleEnter } from "../utils";
36
35
 
37
36
  export interface NumberProps
38
37
  extends InputProps<number>,
@@ -73,10 +72,7 @@ export const Number = ({
73
72
  const [actualValue, setActualValue] = useState<"" | number>("");
74
73
  const deferred = useDeferredValue(value);
75
74
 
76
- const handleEnterPressed = useMemo(
77
- () => handleEnter(onEnterPressed),
78
- [onEnterPressed],
79
- );
75
+ const handleEnterPressed = useHandleEnter(onEnterPressed);
80
76
 
81
77
  useEffect(() => {
82
78
  setActualValue(deferred ?? "");
@@ -28,14 +28,13 @@ import {
28
28
  useCallback,
29
29
  useDeferredValue,
30
30
  useEffect,
31
- useMemo,
32
31
  useState,
33
32
  type ChangeEvent,
34
33
  } from "react";
35
34
  import { useTranslation } from "react-i18next";
36
35
  import { InputWrapper } from "../internal/InputWrapper";
37
36
  import { type InputProps } from "../types";
38
- import { handleEnter } from "../utils";
37
+ import { useHandleEnter } from "../utils";
39
38
 
40
39
  export interface PasswordProps extends InputProps, RefProp<HTMLInputElement> {
41
40
  /**
@@ -72,10 +71,7 @@ export const Password = ({
72
71
  const [actualValue, setActualValue] = useState("");
73
72
  const deferred = useDeferredValue(value);
74
73
 
75
- const handleEnterPressed = useMemo(
76
- () => handleEnter(onEnterPressed),
77
- [onEnterPressed],
78
- );
74
+ const handleEnterPressed = useHandleEnter(onEnterPressed);
79
75
 
80
76
  useEffect(() => {
81
77
  setActualValue(deferred ?? "");