@react-fabric/form 1.0.0-beta.6 → 1.0.0-beta.60

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 (187) hide show
  1. package/{src/input/ArrayInput.module.css → css/_arrayInput.css} +8 -8
  2. package/css/_colorPicker.css +65 -0
  3. package/{src/internal/Field.module.css → css/_field.css} +66 -30
  4. package/{src/input/File.module.css → css/_file.css} +21 -6
  5. package/css/styles.css +27 -0
  6. package/dist/cjs/builder/FileField.js +40 -28
  7. package/dist/cjs/builder/FormField.js +50 -34
  8. package/dist/cjs/builder/SchemaEditor.js +72 -0
  9. package/dist/cjs/builder/components/AddSchemaFields.js +62 -0
  10. package/dist/cjs/builder/components/SchemaArrayForm.js +145 -0
  11. package/dist/cjs/builder/components/SchemaField.js +414 -0
  12. package/dist/cjs/form/Controller.js +46 -1
  13. package/dist/cjs/form/Form.js +70 -9
  14. package/dist/cjs/hooks/useFileUploader.js +16 -0
  15. package/dist/cjs/hooks/useFormBuilder.js +57 -15
  16. package/dist/cjs/i18n/ar.json.js +5 -4
  17. package/dist/cjs/i18n/en.json.js +5 -5
  18. package/dist/cjs/index.js +12 -2
  19. package/dist/cjs/input/ArrayInput.js +126 -36
  20. package/dist/cjs/input/AvatarInput.js +43 -23
  21. package/dist/cjs/input/Checkbox.js +16 -6
  22. package/dist/cjs/input/ColorInput.js +113 -58
  23. package/dist/cjs/input/ColorPicker.js +60 -76
  24. package/dist/cjs/input/DateInput.js +197 -0
  25. package/dist/cjs/input/Field.js +10 -4
  26. package/dist/cjs/input/File.js +14 -7
  27. package/dist/cjs/input/Hidden.js +13 -2
  28. package/dist/cjs/input/Input.js +24 -10
  29. package/dist/cjs/input/Number.js +22 -10
  30. package/dist/cjs/input/Password.js +22 -12
  31. package/dist/cjs/input/Radio.js +12 -3
  32. package/dist/cjs/input/RadioGroup.js +10 -1
  33. package/dist/cjs/input/{Range.js → RangeSlider.js} +16 -8
  34. package/dist/cjs/input/Search.js +30 -19
  35. package/dist/cjs/input/Slider.js +12 -6
  36. package/dist/cjs/input/Switch.js +20 -9
  37. package/dist/cjs/input/Textarea.js +29 -8
  38. package/dist/cjs/internal/ErrorIcon.js +1 -1
  39. package/dist/cjs/internal/FieldWrapper.js +11 -4
  40. package/dist/cjs/internal/InputWrapper.js +27 -20
  41. package/dist/cjs/select/AutoComplete.js +21 -11
  42. package/dist/cjs/select/DualList.js +34 -12
  43. package/dist/cjs/select/List.js +68 -22
  44. package/dist/cjs/select/Options.js +49 -42
  45. package/dist/cjs/select/Select.js +40 -10
  46. package/dist/cjs/select/useSelect.js +22 -11
  47. package/dist/cjs/types/schema.js +43 -0
  48. package/dist/cjs/utils/eventHandlers.js +15 -5
  49. package/dist/esm/builder/FileField.js +42 -30
  50. package/dist/esm/builder/FormField.js +50 -34
  51. package/dist/esm/builder/SchemaEditor.js +72 -0
  52. package/dist/esm/builder/components/AddSchemaFields.js +62 -0
  53. package/dist/esm/builder/components/SchemaArrayForm.js +145 -0
  54. package/dist/esm/builder/components/SchemaField.js +414 -0
  55. package/dist/esm/form/Controller.js +46 -1
  56. package/dist/esm/form/Form.js +72 -12
  57. package/dist/esm/hooks/useFileUploader.js +16 -0
  58. package/dist/esm/hooks/useFormBuilder.js +55 -13
  59. package/dist/esm/i18n/ar.json.js +5 -4
  60. package/dist/esm/i18n/en.json.js +5 -5
  61. package/dist/esm/index.js +6 -2
  62. package/dist/esm/input/ArrayInput.js +126 -36
  63. package/dist/esm/input/AvatarInput.js +44 -24
  64. package/dist/esm/input/Checkbox.js +16 -6
  65. package/dist/esm/input/ColorInput.js +115 -60
  66. package/dist/esm/input/ColorPicker.js +60 -76
  67. package/dist/esm/input/DateInput.js +197 -0
  68. package/dist/esm/input/Field.js +11 -5
  69. package/dist/esm/input/File.js +16 -9
  70. package/dist/esm/input/Hidden.js +13 -2
  71. package/dist/esm/input/Input.js +26 -12
  72. package/dist/esm/input/Number.js +24 -12
  73. package/dist/esm/input/Password.js +24 -14
  74. package/dist/esm/input/Radio.js +12 -3
  75. package/dist/esm/input/RadioGroup.js +11 -2
  76. package/dist/esm/input/{Range.js → RangeSlider.js} +16 -8
  77. package/dist/esm/input/Search.js +32 -21
  78. package/dist/esm/input/Slider.js +12 -6
  79. package/dist/esm/input/Switch.js +20 -9
  80. package/dist/esm/input/Textarea.js +30 -9
  81. package/dist/esm/internal/ErrorIcon.js +1 -1
  82. package/dist/esm/internal/FieldWrapper.js +11 -4
  83. package/dist/esm/internal/InputWrapper.js +27 -20
  84. package/dist/esm/select/AutoComplete.js +21 -11
  85. package/dist/esm/select/DualList.js +34 -12
  86. package/dist/esm/select/List.js +69 -23
  87. package/dist/esm/select/Options.js +49 -42
  88. package/dist/esm/select/Select.js +40 -10
  89. package/dist/esm/select/useSelect.js +23 -12
  90. package/{src/input/ColorPicker.module.css → dist/esm/types/schema.js} +18 -27
  91. package/dist/esm/utils/eventHandlers.js +15 -5
  92. package/dist/types/builder/FileField.d.ts +4 -2
  93. package/dist/types/builder/FormField.d.ts +3 -1
  94. package/dist/types/builder/SchemaEditor.d.ts +9 -0
  95. package/dist/types/builder/components/AddSchemaFields.d.ts +2 -0
  96. package/dist/types/builder/components/SchemaArrayForm.d.ts +2 -0
  97. package/dist/types/builder/components/SchemaField.d.ts +10 -0
  98. package/dist/types/form/Controller.d.ts +47 -2
  99. package/dist/types/form/Form.d.ts +48 -2
  100. package/dist/types/hooks/useFileUploader.d.ts +16 -0
  101. package/dist/types/hooks/useFormBuilder.d.ts +32 -1
  102. package/dist/types/index.d.ts +6 -3
  103. package/dist/types/input/ArrayInput.d.ts +69 -12
  104. package/dist/types/input/AvatarInput.d.ts +23 -3
  105. package/dist/types/input/Checkbox.d.ts +13 -4
  106. package/dist/types/input/ColorInput.d.ts +15 -2
  107. package/dist/types/input/ColorPicker.d.ts +11 -1
  108. package/dist/types/input/DateInput.d.ts +28 -0
  109. package/dist/types/input/Field.d.ts +5 -1
  110. package/dist/types/input/File.d.ts +9 -0
  111. package/dist/types/input/Hidden.d.ts +13 -1
  112. package/dist/types/input/Input.d.ts +9 -1
  113. package/dist/types/input/Number.d.ts +9 -1
  114. package/dist/types/input/Password.d.ts +7 -1
  115. package/dist/types/input/Radio.d.ts +9 -1
  116. package/dist/types/input/RadioGroup.d.ts +8 -1
  117. package/dist/types/input/RangeSlider.d.ts +67 -0
  118. package/dist/types/input/Search.d.ts +14 -1
  119. package/dist/types/input/Slider.d.ts +8 -2
  120. package/dist/types/input/Switch.d.ts +10 -2
  121. package/dist/types/input/Textarea.d.ts +15 -1
  122. package/dist/types/internal/FieldWrapper.d.ts +1 -1
  123. package/dist/types/internal/InputWrapper.d.ts +1 -1
  124. package/dist/types/ranger/index.d.ts +2 -2
  125. package/dist/types/select/AutoComplete.d.ts +8 -1
  126. package/dist/types/select/DualList.d.ts +17 -2
  127. package/dist/types/select/List.d.ts +9 -1
  128. package/dist/types/select/Options.d.ts +4 -3
  129. package/dist/types/select/Select.d.ts +9 -1
  130. package/dist/types/select/useSelect.d.ts +10 -6
  131. package/dist/types/types/index.d.ts +34 -5
  132. package/dist/types/types/schema.d.ts +78 -33
  133. package/dist/types/utils/eventHandlers.d.ts +2 -2
  134. package/package.json +22 -20
  135. package/src/builder/FileField.tsx +62 -30
  136. package/src/builder/FormField.tsx +52 -32
  137. package/src/builder/SchemaEditor.tsx +79 -0
  138. package/src/builder/components/AddSchemaFields.tsx +74 -0
  139. package/src/builder/components/SchemaArrayForm.tsx +161 -0
  140. package/src/builder/components/SchemaField.tsx +436 -0
  141. package/src/form/Controller.tsx +48 -3
  142. package/src/form/Form.tsx +80 -8
  143. package/src/hooks/useFileUploader.ts +16 -0
  144. package/src/hooks/useFormBuilder.tsx +58 -15
  145. package/src/i18n/ar.json +5 -4
  146. package/src/i18n/en.json +5 -5
  147. package/src/index.ts +12 -3
  148. package/src/input/ArrayInput.tsx +199 -64
  149. package/src/input/AvatarInput.tsx +67 -19
  150. package/src/input/Checkbox.tsx +16 -6
  151. package/src/input/ColorInput.tsx +131 -71
  152. package/src/input/ColorPicker.tsx +54 -72
  153. package/src/input/DateInput.tsx +260 -0
  154. package/src/input/Field.tsx +15 -11
  155. package/src/input/File.tsx +16 -14
  156. package/src/input/Hidden.tsx +17 -2
  157. package/src/input/Input.tsx +27 -13
  158. package/src/input/Number.tsx +22 -13
  159. package/src/input/Password.tsx +24 -16
  160. package/src/input/Radio.tsx +12 -3
  161. package/src/input/RadioGroup.tsx +12 -3
  162. package/src/input/{Range.tsx → RangeSlider.tsx} +17 -9
  163. package/src/input/Search.tsx +33 -22
  164. package/src/input/Slider.tsx +20 -11
  165. package/src/input/Switch.tsx +17 -6
  166. package/src/input/Textarea.tsx +34 -9
  167. package/src/internal/ErrorIcon.tsx +1 -1
  168. package/src/internal/FieldWrapper.tsx +8 -4
  169. package/src/internal/InputWrapper.tsx +49 -27
  170. package/src/select/AutoComplete.tsx +14 -3
  171. package/src/select/DualList.tsx +31 -16
  172. package/src/select/List.tsx +52 -8
  173. package/src/select/Options.tsx +50 -46
  174. package/src/select/Select.tsx +25 -5
  175. package/src/select/useSelect.tsx +26 -9
  176. package/src/types/index.ts +37 -6
  177. package/src/types/schema.ts +96 -41
  178. package/src/utils/eventHandlers.ts +14 -4
  179. package/dist/cjs/input/ArrayInput.module.css +0 -1
  180. package/dist/cjs/input/ColorPicker.module.css +0 -1
  181. package/dist/cjs/input/File.module.css +0 -1
  182. package/dist/cjs/internal/Field.module.css +0 -1
  183. package/dist/esm/input/ArrayInput.module.css +0 -1
  184. package/dist/esm/input/ColorPicker.module.css +0 -1
  185. package/dist/esm/input/File.module.css +0 -1
  186. package/dist/esm/internal/Field.module.css +0 -1
  187. package/dist/types/input/Range.d.ts +0 -59
@@ -1,4 +1,12 @@
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, createOption, matcher, renderer, onQuery, onChange, onSelect, onEnterPressed, invalid, error, allowClear, decorateStart, decorateEnd, "data-inner": isInner, "data-hide-selected": hideSelected, ...rest }: SelectProps<T> & {
2
+ /**
3
+ * List component for selecting items from a list.
4
+ * It supports single and multiple selections, searching, creating new options,
5
+ * and custom rendering of options.
6
+ *
7
+ * @param {SelectProps<T>} props - The properties for the List component.
8
+ * @returns {JSX.Element} The rendered List component.
9
+ */
10
+ export declare const List: <T extends AnyObject = string>({ ref, name, value, readOnly, disabled, required, placeholder, autoFocus, options, height, groupProperty, labelProperty, valueProperty, infoProperty, 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
11
  height?: string | number;
4
12
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,7 @@
1
- import { type ReactElement, type ReactNode } from "react";
2
- export declare const Options: ({ ref, style, items, active, className, itemRef, empty, valueProperty, labelProperty, itemProps, children, ...rest }: {
1
+ import { type ReactElement } from "react";
2
+ export declare const Options: ({ ref, style, items, active, className, itemRef, empty, info, valueProperty, labelProperty, itemProps, children, ...rest }: {
3
3
  ref: AnyObject;
4
+ info?: AnyObject;
4
5
  itemRef: AnyObject;
5
6
  style?: AnyObject;
6
7
  items: AnyObject[];
@@ -10,5 +11,5 @@ export declare const Options: ({ ref, style, items, active, className, itemRef,
10
11
  valueProperty?: AnyObject;
11
12
  labelProperty?: AnyObject;
12
13
  itemProps: (item: AnyObject) => AnyObject;
13
- children: (item: AnyObject, label: string) => ReactNode;
14
+ children: (item: AnyObject, label: string) => React.ReactNode;
14
15
  } & KeyValue) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,10 @@
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, groupProperty, labelProperty, valueProperty, multiple, searchable, allowCreate, createOption, matcher, renderer, onQuery, onChange, onSelect, onEnterPressed, ...rest }: SelectProps<T>) => import("react/jsx-runtime").JSX.Element;
2
+ /**
3
+ * Select component for selecting items from a dropdown list.
4
+ * It supports single and multiple selections, searching, creating new options,
5
+ * and custom rendering of options.
6
+ *
7
+ * @param {SelectProps<T>} props - The properties for the Select component.
8
+ * @returns {JSX.Element} The rendered Select component.
9
+ */
10
+ export declare const Select: <T extends AnyObject = string>({ ref, name, value, invalid, readOnly, disabled, required, placeholder, autoFocus, error, options, defaultOpen, hideHandle, groupProperty, labelProperty, valueProperty, sortProperty, infoProperty, multiple, searchable, allowCreate, emptyDisplay, createOption, matcher, renderer, onQuery, onChange, onSelect, onEnterPressed, ...rest }: SelectProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -1,23 +1,26 @@
1
- /// <reference types="react" />
2
1
  interface State {
3
2
  multiple: boolean;
4
3
  emptyValue: AnyObject;
5
4
  open: boolean;
6
5
  loading: boolean;
7
6
  activeIndex: number | null;
7
+ activeItem: AnyObject;
8
8
  selectedIndex: number | null;
9
9
  value: AnyObject;
10
10
  query?: string;
11
11
  items: AnyObject[];
12
12
  }
13
- export declare const useSelect: ({ options, value, autoComplete, multiple, allowCreate, groupProperty, valueProperty, labelProperty, createOption, matcher, onQuery, onChange, onSelect, }: {
13
+ export declare const useSelect: ({ options, value, autoComplete, alwaysOpen, defaultOpen, multiple, allowCreate, groupProperty, valueProperty, labelProperty, sortProperty, createOption, matcher, onQuery, onChange, onSelect, }: {
14
14
  value?: AnyObject;
15
15
  options?: AnyObject[];
16
16
  multiple?: boolean;
17
+ alwaysOpen?: boolean;
18
+ defaultOpen?: boolean;
17
19
  allowCreate?: boolean;
18
20
  groupProperty?: AnyObject;
19
21
  valueProperty?: AnyObject;
20
22
  labelProperty?: AnyObject;
23
+ sortProperty?: AnyObject;
21
24
  autoComplete?: boolean;
22
25
  matcher?: (item: AnyObject, query: string) => boolean;
23
26
  createOption?: (query: string) => AnyObject;
@@ -28,17 +31,18 @@ export declare const useSelect: ({ options, value, autoComplete, multiple, allow
28
31
  state: State | {
29
32
  value: any;
30
33
  activeIndex: null;
34
+ activeItem: null;
31
35
  selectedIndex: any;
32
36
  multiple: boolean;
33
37
  emptyValue: AnyObject;
34
38
  open: boolean;
35
39
  loading: boolean;
36
- query?: string | undefined;
40
+ query?: string;
37
41
  items: AnyObject[];
38
42
  };
39
- listRef: import("react").MutableRefObject<HTMLElement[]>;
40
- focusableRef: import("react").RefObject<HTMLElement>;
41
- listContentRef: import("react").MutableRefObject<any[]>;
43
+ listRef: import("react").RefObject<HTMLElement[]>;
44
+ focusableRef: import("react").RefObject<HTMLElement | null>;
45
+ listContentRef: import("react").RefObject<any[]>;
42
46
  handleChange: (value?: AnyObject) => void;
43
47
  handleRemove: (index?: number) => void;
44
48
  handleQuery: (query: string) => void;
@@ -1,14 +1,18 @@
1
- /// <reference types="react" />
2
1
  import { type RefProp, type TestProps } from "@react-fabric/core/dist/types/types";
2
+ import { type ReactElement } from "react";
3
3
  export interface InputProps<V = string> extends TestProps {
4
4
  /**
5
5
  * value
6
6
  */
7
- value?: V;
7
+ value?: V | null;
8
+ /**
9
+ * default value
10
+ */
11
+ defaultValue?: V | null;
8
12
  /**
9
13
  * change handler
10
14
  */
11
- onChange?: (value?: V) => void;
15
+ onChange?: (value: V | null) => void;
12
16
  /**
13
17
  * on focus event handler
14
18
  */
@@ -45,10 +49,13 @@ export interface InputProps<V = string> extends TestProps {
45
49
  *
46
50
  */
47
51
  decorateEnd?: JSX.Element | string | number | boolean;
52
+ decorateEndShowWhenEmpty?: boolean;
53
+ decorateEndHideWhenEmpty?: boolean;
48
54
  /**
49
55
  * info label at bottom
50
56
  */
51
57
  info?: string;
58
+ monospace?: boolean;
52
59
  /**
53
60
  * required
54
61
  */
@@ -90,7 +97,15 @@ export interface InputProps<V = string> extends TestProps {
90
97
  */
91
98
  labelWidth?: string;
92
99
  }
93
- export interface BaseSelectProps<T> extends RefProp<HTMLInputElement>, Omit<InputProps, "value" | "onChange"> {
100
+ export interface BaseSelectProps<T extends AnyObject = string> {
101
+ /**
102
+ * open dropdown by default
103
+ */
104
+ defaultOpen?: boolean;
105
+ /**
106
+ * hide dropdown handle
107
+ */
108
+ hideHandle?: boolean;
94
109
  /**
95
110
  * list options
96
111
  */
@@ -107,6 +122,14 @@ export interface BaseSelectProps<T> extends RefProp<HTMLInputElement>, Omit<Inpu
107
122
  * value property name
108
123
  */
109
124
  valueProperty?: keyof T;
125
+ /**
126
+ * value property name
127
+ */
128
+ infoProperty?: keyof T;
129
+ /**
130
+ * value property name
131
+ */
132
+ sortProperty?: keyof T | true;
110
133
  /**
111
134
  * searchable list
112
135
  */
@@ -115,6 +138,10 @@ export interface BaseSelectProps<T> extends RefProp<HTMLInputElement>, Omit<Inpu
115
138
  * allow create item
116
139
  */
117
140
  allowCreate?: boolean;
141
+ /**
142
+ * empty list display
143
+ */
144
+ emptyDisplay?: ReactElement;
118
145
  /**
119
146
  * create new item object
120
147
  */
@@ -132,7 +159,8 @@ export interface BaseSelectProps<T> extends RefProp<HTMLInputElement>, Omit<Inpu
132
159
  */
133
160
  matcher?: (option: T, query: string) => boolean;
134
161
  }
135
- export type SelectProps<T> = BaseSelectProps<T> & ({
162
+ type BaseSelectType<T> = BaseSelectProps<T> & RefProp<HTMLInputElement> & Omit<InputProps, "value" | "onChange">;
163
+ export type SelectProps<T> = BaseSelectType<T> & ({
136
164
  /**
137
165
  * is multiple selection
138
166
  */
@@ -167,3 +195,4 @@ export type SelectProps<T> = BaseSelectProps<T> & ({
167
195
  */
168
196
  onChange?: (value?: string[]) => void;
169
197
  });
198
+ export {};
@@ -1,59 +1,104 @@
1
- interface BaseSchemaDef {
1
+ import { type Elements } from "@react-fabric/core/dist/types/types";
2
+ import { type DateLike } from "@react-fabric/date";
3
+ export declare enum DATA_TYPES {
4
+ TEXT = "text",
5
+ COLOR = "color",
6
+ BOOL = "bool",
7
+ DATE = "date",
8
+ DATETIME = "datetime",
9
+ STRING = "string",
10
+ NUMBER = "number",
11
+ RANGE = "range",
12
+ FILE = "file",
13
+ AVATAR = "avatar",
14
+ SCHEMA = "schema"
15
+ }
16
+ export declare const SCHEMA_CUSTOM_LIST = "--CUSTOM--";
17
+ interface SingleValue {
18
+ multiple?: false;
19
+ minItems?: never;
20
+ maxItems?: never;
21
+ }
22
+ interface MultipleValue {
23
+ multiple: true;
24
+ minItems?: number;
25
+ maxItems?: number;
26
+ }
27
+ export type ValueType = SingleValue | MultipleValue;
28
+ interface BaseSchema {
2
29
  id: string;
3
30
  label: string;
4
31
  datatype: string;
5
32
  required?: boolean;
6
- multiple?: boolean;
7
- defaultValue?: AnyObject;
8
33
  }
9
- interface SchemaDef extends BaseSchemaDef {
10
- datatype: "text" | "color";
34
+ export interface DefaultSchema extends BaseSchema {
35
+ datatype: DATA_TYPES.TEXT | DATA_TYPES.COLOR;
11
36
  }
12
- interface BooleanSchema extends BaseSchemaDef {
13
- datatype: "boolean";
14
- defaultValue?: boolean;
37
+ export interface BooleanSchema extends BaseSchema {
38
+ datatype: DATA_TYPES.BOOL;
15
39
  }
16
- interface StringSchema extends BaseSchemaDef {
17
- datatype: "string";
18
- options?: string[];
40
+ export interface StringSchema extends BaseSchema {
41
+ datatype: DATA_TYPES.STRING;
19
42
  regex?: string;
20
- identifierType?: string;
43
+ options?: string[];
44
+ optionList?: string;
45
+ allowCustom?: boolean;
21
46
  }
22
- interface RangeSchema extends BaseSchemaDef {
23
- datatype: "range";
47
+ export interface RangeSchema extends BaseSchema {
48
+ datatype: DATA_TYPES.RANGE;
24
49
  min?: number;
25
50
  max?: number;
26
51
  step?: number;
27
- defaultValue?: [number, number];
28
52
  }
29
- interface NumberSchema extends BaseSchemaDef {
30
- datatype: "number";
31
- min?: number;
32
- max?: number;
33
- step?: number;
34
- defaultValue?: number;
53
+ export interface DateSchema extends BaseSchema {
54
+ datatype: DATA_TYPES.DATE | DATA_TYPES.DATETIME;
55
+ min?: DateLike;
56
+ max?: DateLike;
35
57
  }
36
- interface DecimalSchema extends BaseSchemaDef {
37
- datatype: "decimal";
58
+ export interface NumberSchema extends BaseSchema {
59
+ datatype: DATA_TYPES.NUMBER;
38
60
  min?: number;
39
61
  max?: number;
40
62
  step?: number;
41
- defaultValue?: number;
42
63
  }
43
- export interface FileSchema extends BaseSchemaDef {
44
- datatype: "file";
64
+ export interface FileSchema extends BaseSchema {
65
+ datatype: DATA_TYPES.FILE;
45
66
  accept?: string;
46
67
  }
47
- export interface AvatarSchema extends BaseSchemaDef {
48
- datatype: "avatar";
68
+ export interface AvatarSchema extends BaseSchema {
69
+ datatype: DATA_TYPES.AVATAR;
49
70
  multiple?: false;
50
71
  }
51
- export type SchemaType = SchemaDef | BooleanSchema | StringSchema | RangeSchema | NumberSchema | DecimalSchema | FileSchema | AvatarSchema;
52
- export interface ChildSchema extends BaseSchemaDef {
53
- datatype: "schema";
72
+ export type SchemaType = (DefaultSchema & ValueType) | (BooleanSchema & ValueType) | (StringSchema & ValueType) | (RangeSchema & ValueType) | (DateSchema & ValueType) | (NumberSchema & ValueType) | (FileSchema & ValueType) | (AvatarSchema & ValueType);
73
+ export interface ChildSchema extends BaseSchema {
74
+ datatype: DATA_TYPES.SCHEMA;
54
75
  inline?: boolean;
55
76
  schema: SchemaType[];
56
- defaultValue?: never;
57
77
  }
58
- export type FormSchema = SchemaType | ChildSchema;
78
+ export type SchemaDef = SchemaType | (ChildSchema & ValueType);
79
+ export type FormSchema = SchemaDef[];
80
+ export interface SchemaEditorProps {
81
+ /**
82
+ * default form schema
83
+ */
84
+ schemaDef: FormSchema;
85
+ /**
86
+ * is dynamic schema (allow add/remove)
87
+ */
88
+ dynamic?: boolean;
89
+ /**
90
+ * acceptable list of data types
91
+ */
92
+ acceptableTypes?: DATA_TYPES[];
93
+ /**
94
+ * available option lists in application
95
+ */
96
+ optionLists?: string[];
97
+ /**
98
+ * footer actions
99
+ */
100
+ children?: Elements<JSX.Element> | Array<Elements<JSX.Element>>;
101
+ onChange?: (schema: FormSchema) => void;
102
+ onSubmit?: (schema: FormSchema) => void;
103
+ }
59
104
  export {};
@@ -1,9 +1,9 @@
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
- }) => (e: KeyboardEvent) => false | undefined;
6
+ }) => (e: KeyboardEvent<HTMLInputElement>) => false | undefined;
7
7
  /** ***************** common handler for mouse primary click *******************/
8
8
  export declare const handleClick: (callback?: (e: MouseEvent) => void, { stopPropagation, preventDefault, }?: {
9
9
  stopPropagation?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-fabric/form",
3
- "version": "1.0.0-beta.6",
3
+ "version": "1.0.0-beta.60",
4
4
  "description": "RUF: Form package",
5
5
  "author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
6
6
  "license": "MIT",
@@ -11,9 +11,11 @@
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
  ],
@@ -33,32 +35,32 @@
33
35
  "watch": "npm-run-all -p watch:rollup watch:dts"
34
36
  },
35
37
  "dependencies": {
36
- "@dnd-kit/core": "^6.1.0",
37
- "@dnd-kit/modifiers": "^7.0.0",
38
- "@dnd-kit/sortable": "^8.0.0",
39
- "@dnd-kit/utilities": "^3.2.2",
40
- "@floating-ui/react": "0.26.24",
41
- "@hookform/resolvers": "^3.9.0",
42
- "@react-fabric/core": "^1.0.0-beta.6",
43
- "@react-fabric/utilities": "^1.0.0-beta.6",
44
- "classnames": "^2.5.1",
45
- "color": "^4.2.3",
46
- "react-color": "^2.19.3",
47
- "react-hook-form": "^7.52.1"
38
+ "@dnd-kit/core": "~6.3.1",
39
+ "@dnd-kit/modifiers": "~9.0.0",
40
+ "@dnd-kit/sortable": "~10.0.0",
41
+ "@dnd-kit/utilities": "~3.2.2",
42
+ "@floating-ui/react": "~0.27.16",
43
+ "@hookform/resolvers": "~5.2.2",
44
+ "@react-fabric/core": "^1.0.0-beta.60",
45
+ "@react-fabric/date": "^1.0.0-beta.60",
46
+ "@react-fabric/utilities": "^1.0.0-beta.60",
47
+ "classnames": "~2.5.1",
48
+ "color": "~5.0.2",
49
+ "react-color": "~2.19.3",
50
+ "react-hook-form": "~7.65.0"
48
51
  },
49
52
  "peerDependencies": {
50
- "i18next": "^23.15.1",
51
- "react": ">=18.0.0 <20.0.0",
52
- "react-dom": ">=18.0.0 <20.0.0",
53
- "react-i18next": "^15.0.2"
53
+ "i18next": "~25.6.0",
54
+ "react": "~19.2.0",
55
+ "react-dom": "~19.2.0",
56
+ "react-i18next": "~16.2.1"
54
57
  },
55
58
  "devDependencies": {
56
- "@types/axios": "^0.14.0",
57
- "@types/react-color": "^3.0.12"
59
+ "@types/react-color": "~3.0.13"
58
60
  },
59
61
  "engines": {
60
62
  "node": ">=18.12.0",
61
63
  "npm": ">=8.19.0"
62
64
  },
63
- "gitHead": "21167df13cedeae8b365e87b9bab6d7401298cb6"
65
+ "gitHead": "a79f053ee7e13422c06d7d9c35d4f0c2610cdf5d"
64
66
  }
@@ -21,28 +21,41 @@
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 {
25
+ Button,
26
+ CoreIcons,
27
+ Icon,
28
+ ProgressBar,
29
+ Tooltip,
30
+ } from "@react-fabric/core";
31
+ import { FileUtil, Format, isString } from "@react-fabric/utilities";
26
32
  import { Fragment } from "react";
27
- import { type UploadHandler, useFileUploader } from "../hooks/useFileUploader";
33
+ import { useTranslation } from "react-i18next";
34
+ import { useFileUploader, type UploadHandler } from "../hooks/useFileUploader";
28
35
  import { Field } from "../input/Field";
29
36
  import { HiddenInput } from "../input/Hidden";
30
- import { type FileSchema } from "../types/schema";
37
+ import { type FileSchema, type ValueType } from "../types/schema";
31
38
 
32
39
  export const FileField = ({
33
40
  uploadHandler,
34
41
  inline,
35
42
  label,
36
43
  accept,
37
- multiple = false,
38
44
  value,
45
+ fileUrl,
46
+ multiple,
47
+ invalid,
48
+ error,
39
49
  ...rest
40
- }: Partial<FileSchema> & {
50
+ }: Partial<FileSchema & ValueType> & {
41
51
  value?: AnyObject;
42
52
  inline?: boolean;
53
+ invalid?: boolean;
54
+ error?: AnyObject;
43
55
  fileUrl?: (path: string) => string;
44
56
  uploadHandler: UploadHandler;
45
57
  }) => {
58
+ const { t } = useTranslation();
46
59
  const { pending, files, list, upload, remove } = useFileUploader(
47
60
  async (data, config) => await uploadHandler?.(data, config),
48
61
  value,
@@ -51,29 +64,48 @@ export const FileField = ({
51
64
 
52
65
  return (
53
66
  <Fragment>
54
- <Field plain inline={inline} label={label} className="inline-block">
67
+ <Field plain inline={inline} label={label}>
55
68
  <HiddenInput hiddenValue={multiple ? list : list?.[0]} {...rest} />
56
- <span>
57
- <Button
58
- badge={pending > 0 ? `${pending}` : undefined}
59
- data-ref="filebtn"
60
- >
61
- <Fragment>
62
- <span>Add file</span>
63
- <input
64
- type="file"
65
- accept={accept}
66
- multiple={multiple}
67
- className="absolute inset-0 opacity-0 z-5"
68
- onChange={(e) => [
69
- upload(e.target.files),
70
- (e.target.value = ""),
71
- ]}
72
- />
73
- </Fragment>
74
- </Button>
75
- </span>
76
69
  </Field>
70
+ <Tooltip
71
+ color="danger-200"
72
+ content={
73
+ isString(error)
74
+ ? `${error}`
75
+ : error &&
76
+ (t(
77
+ error?.key,
78
+ error.values
79
+ ? {
80
+ ...error?.values,
81
+ label: t(
82
+ error.values?.label ?? "form:badkey",
83
+ error.values?.path,
84
+ ),
85
+ }
86
+ : {},
87
+ ) as string)
88
+ }
89
+ disabled={!error}
90
+ >
91
+ <Button
92
+ badge={pending > 0 ? `${pending}` : undefined}
93
+ color={error ? "danger" : undefined}
94
+ variant={error ? "soft" : undefined}
95
+ data-ref="filebtn"
96
+ >
97
+ <Fragment>
98
+ <span>Add file</span>
99
+ <input
100
+ type="file"
101
+ accept={accept}
102
+ multiple={multiple}
103
+ className="absolute inset-0 opacity-0 z-5"
104
+ onChange={(e) => [upload(e.target.files), (e.target.value = "")]}
105
+ />
106
+ </Fragment>
107
+ </Button>
108
+ </Tooltip>
77
109
  <br />
78
110
  <div className="bg-alternate">
79
111
  {files.map((file, idx) => (
@@ -92,18 +124,18 @@ export const FileField = ({
92
124
  </div>
93
125
  {file.progress && (
94
126
  <Icon
95
- icon="mdi mdi-stop-circle"
127
+ icon={CoreIcons.stop}
96
128
  bg="danger"
97
129
  color="white"
98
130
  size="sm"
99
- className="p-[2px]"
131
+ className="p-0.5"
100
132
  aria-label="abort"
101
133
  onClick={() => file.abort?.()}
102
134
  />
103
135
  )}
104
136
  {!file.progress && (
105
137
  <Icon
106
- icon="mdi mdi-trash-can"
138
+ icon={CoreIcons.trash}
107
139
  color="danger"
108
140
  size="sm"
109
141
  aria-label="remove"