@react-fabric/form 1.0.0-beta.9 → 1.0.2

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 (215) hide show
  1. package/{src/input/ArrayInput.module.css → css/_arrayInput.css} +8 -8
  2. package/css/_colorPicker.css +95 -0
  3. package/{src/internal/Field.module.css → css/_field.css} +94 -33
  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 +107 -78
  7. package/dist/cjs/builder/FormField.js +60 -39
  8. package/dist/cjs/builder/SchemaEditor.js +72 -0
  9. package/dist/cjs/builder/components/AddSchemaFields.js +64 -0
  10. package/dist/cjs/builder/components/SchemaArrayForm.js +146 -0
  11. package/dist/cjs/builder/components/SchemaField.js +423 -0
  12. package/dist/cjs/form/Controller.js +66 -19
  13. package/dist/cjs/form/Form.js +97 -39
  14. package/dist/cjs/form/useForm.js +32 -0
  15. package/dist/cjs/hooks/useFileUploader.js +74 -45
  16. package/dist/cjs/hooks/useFormBuilder.js +85 -31
  17. package/dist/cjs/i18n/{ar.json.js → ar/form.json.js} +5 -4
  18. package/dist/cjs/i18n/{en.json.js → en/form.json.js} +5 -5
  19. package/dist/cjs/i18n/index.js +4 -4
  20. package/dist/cjs/index.js +41 -2
  21. package/dist/cjs/input/ArrayInput.js +259 -135
  22. package/dist/cjs/input/AvatarInput.js +99 -63
  23. package/dist/cjs/input/Checkbox.js +24 -25
  24. package/dist/cjs/input/ColorInput.js +138 -81
  25. package/dist/cjs/input/ColorPicker.js +78 -95
  26. package/dist/cjs/input/DateInput.js +192 -0
  27. package/dist/cjs/input/Field.js +21 -20
  28. package/dist/cjs/input/File.js +85 -80
  29. package/dist/cjs/input/Hidden.js +27 -13
  30. package/dist/cjs/input/Input.js +49 -48
  31. package/dist/cjs/input/Number.js +46 -44
  32. package/dist/cjs/input/Password.js +51 -49
  33. package/dist/cjs/input/Radio.js +26 -16
  34. package/dist/cjs/input/RadioGroup.js +26 -11
  35. package/dist/cjs/input/{Range.js → RangeSlider.js} +61 -66
  36. package/dist/cjs/input/Search.js +58 -64
  37. package/dist/cjs/input/Slider.js +57 -66
  38. package/dist/cjs/input/Switch.js +29 -27
  39. package/dist/cjs/input/Textarea.js +65 -53
  40. package/dist/cjs/internal/ErrorIcon.js +9 -9
  41. package/dist/cjs/internal/FieldWrapper.js +23 -13
  42. package/dist/cjs/internal/InputWrapper.js +85 -87
  43. package/dist/cjs/ranger/index.js +7 -7
  44. package/dist/cjs/ranger/utils.js +9 -4
  45. package/dist/cjs/select/AutoComplete.js +93 -76
  46. package/dist/cjs/select/DualList.js +235 -154
  47. package/dist/cjs/select/List.js +122 -89
  48. package/dist/cjs/select/Options.js +58 -54
  49. package/dist/cjs/select/Select.js +119 -89
  50. package/dist/cjs/select/helpers.js +5 -5
  51. package/dist/cjs/select/useSelect.js +83 -58
  52. package/dist/cjs/types/schema.js +43 -0
  53. package/dist/cjs/utils/eventHandlers.js +16 -6
  54. package/dist/cjs/utils/getColor.js +6 -6
  55. package/dist/cjs/utils/getProps.js +49 -0
  56. package/dist/esm/builder/FileField.js +109 -80
  57. package/dist/esm/builder/FormField.js +60 -39
  58. package/dist/esm/builder/SchemaEditor.js +72 -0
  59. package/dist/esm/builder/components/AddSchemaFields.js +64 -0
  60. package/dist/esm/builder/components/SchemaArrayForm.js +146 -0
  61. package/dist/esm/builder/components/SchemaField.js +423 -0
  62. package/dist/esm/form/Controller.js +66 -19
  63. package/dist/esm/form/Form.js +97 -39
  64. package/dist/esm/form/useForm.js +32 -0
  65. package/dist/esm/hooks/useFileUploader.js +75 -46
  66. package/dist/esm/hooks/useFormBuilder.js +84 -30
  67. package/dist/esm/i18n/{ar.json.js → ar/form.json.js} +5 -4
  68. package/dist/esm/i18n/{en.json.js → en/form.json.js} +5 -5
  69. package/dist/esm/i18n/index.js +2 -2
  70. package/dist/esm/index.js +36 -1
  71. package/dist/esm/input/ArrayInput.js +260 -136
  72. package/dist/esm/input/AvatarInput.js +99 -63
  73. package/dist/esm/input/Checkbox.js +26 -27
  74. package/dist/esm/input/ColorInput.js +141 -84
  75. package/dist/esm/input/ColorPicker.js +80 -97
  76. package/dist/esm/input/DateInput.js +192 -0
  77. package/dist/esm/input/Field.js +21 -20
  78. package/dist/esm/input/File.js +89 -84
  79. package/dist/esm/input/Hidden.js +28 -14
  80. package/dist/esm/input/Input.js +51 -50
  81. package/dist/esm/input/Number.js +48 -46
  82. package/dist/esm/input/Password.js +54 -52
  83. package/dist/esm/input/Radio.js +27 -17
  84. package/dist/esm/input/RadioGroup.js +27 -12
  85. package/dist/esm/input/{Range.js → RangeSlider.js} +62 -67
  86. package/dist/esm/input/Search.js +61 -67
  87. package/dist/esm/input/Slider.js +58 -67
  88. package/dist/esm/input/Switch.js +31 -29
  89. package/dist/esm/input/Textarea.js +67 -55
  90. package/dist/esm/internal/ErrorIcon.js +11 -11
  91. package/dist/esm/internal/FieldWrapper.js +23 -13
  92. package/dist/esm/internal/InputWrapper.js +88 -90
  93. package/dist/esm/ranger/index.js +7 -7
  94. package/dist/esm/ranger/utils.js +9 -4
  95. package/dist/esm/select/AutoComplete.js +95 -78
  96. package/dist/esm/select/DualList.js +233 -152
  97. package/dist/esm/select/List.js +125 -92
  98. package/dist/esm/select/Options.js +58 -54
  99. package/dist/esm/select/Select.js +122 -92
  100. package/dist/esm/select/helpers.js +5 -5
  101. package/dist/esm/select/useSelect.js +84 -59
  102. package/{src/input/ColorPicker.module.css → dist/esm/types/schema.js} +18 -27
  103. package/dist/esm/utils/eventHandlers.js +16 -6
  104. package/dist/esm/utils/getColor.js +6 -6
  105. package/dist/esm/utils/getProps.js +49 -0
  106. package/dist/types/builder/FileField.d.ts +7 -4
  107. package/dist/types/builder/FormField.d.ts +4 -2
  108. package/dist/types/builder/SchemaEditor.d.ts +6 -0
  109. package/dist/types/builder/components/AddSchemaFields.d.ts +2 -0
  110. package/dist/types/builder/components/SchemaArrayForm.d.ts +2 -0
  111. package/dist/types/builder/components/SchemaField.d.ts +12 -0
  112. package/dist/types/form/Controller.d.ts +45 -3
  113. package/dist/types/form/Form.d.ts +38 -7
  114. package/dist/types/form/useForm.d.ts +6 -0
  115. package/dist/types/hooks/useFileUploader.d.ts +24 -3
  116. package/dist/types/hooks/useFormBuilder.d.ts +41 -3
  117. package/dist/types/index.d.ts +32 -2
  118. package/dist/types/input/ArrayInput.d.ts +68 -13
  119. package/dist/types/input/AvatarInput.d.ts +23 -6
  120. package/dist/types/input/Checkbox.d.ts +12 -10
  121. package/dist/types/input/ColorInput.d.ts +15 -5
  122. package/dist/types/input/ColorPicker.d.ts +10 -2
  123. package/dist/types/input/DateInput.d.ts +21 -0
  124. package/dist/types/input/Field.d.ts +9 -36
  125. package/dist/types/input/File.d.ts +16 -4
  126. package/dist/types/input/Hidden.d.ts +7 -6
  127. package/dist/types/input/Input.d.ts +11 -4
  128. package/dist/types/input/Number.d.ts +9 -4
  129. package/dist/types/input/Password.d.ts +9 -4
  130. package/dist/types/input/Radio.d.ts +9 -4
  131. package/dist/types/input/RadioGroup.d.ts +14 -6
  132. package/dist/types/input/{Range.d.ts → RangeSlider.d.ts} +11 -6
  133. package/dist/types/input/Search.d.ts +14 -4
  134. package/dist/types/input/Slider.d.ts +9 -6
  135. package/dist/types/input/Switch.d.ts +13 -8
  136. package/dist/types/input/Textarea.d.ts +15 -4
  137. package/dist/types/internal/ErrorIcon.d.ts +4 -1
  138. package/dist/types/internal/FieldWrapper.d.ts +10 -1
  139. package/dist/types/internal/InputWrapper.d.ts +19 -1
  140. package/dist/types/ranger/index.d.ts +7 -3
  141. package/dist/types/ranger/utils.d.ts +2 -2
  142. package/dist/types/select/AutoComplete.d.ts +7 -2
  143. package/dist/types/select/DualList.d.ts +11 -37
  144. package/dist/types/select/List.d.ts +7 -2
  145. package/dist/types/select/Options.d.ts +8 -7
  146. package/dist/types/select/Select.d.ts +7 -2
  147. package/dist/types/select/helpers.d.ts +2 -2
  148. package/dist/types/select/useSelect.d.ts +10 -28
  149. package/dist/types/types/index.d.ts +73 -39
  150. package/dist/types/types/schema.d.ts +78 -32
  151. package/dist/types/utils/eventHandlers.d.ts +4 -4
  152. package/dist/types/utils/getColor.d.ts +4 -4
  153. package/dist/types/utils/getProps.d.ts +26 -0
  154. package/dist/types/utils/index.d.ts +1 -0
  155. package/package.json +25 -25
  156. package/src/builder/FileField.tsx +73 -56
  157. package/src/builder/FormField.tsx +66 -58
  158. package/src/builder/SchemaEditor.tsx +78 -0
  159. package/src/builder/components/AddSchemaFields.tsx +64 -0
  160. package/src/builder/components/SchemaArrayForm.tsx +146 -0
  161. package/src/builder/components/SchemaField.tsx +405 -0
  162. package/src/form/Controller.tsx +61 -24
  163. package/src/form/Form.tsx +74 -50
  164. package/src/form/useForm.ts +53 -0
  165. package/src/hooks/useFileUploader.ts +115 -84
  166. package/src/hooks/useFormBuilder.tsx +80 -41
  167. package/src/i18n/{ar.json → ar/form.json} +5 -4
  168. package/src/i18n/{en.json → en/form.json} +5 -5
  169. package/src/i18n/index.ts +2 -2
  170. package/src/index.ts +34 -20
  171. package/src/input/ArrayInput.tsx +255 -173
  172. package/src/input/AvatarInput.tsx +82 -39
  173. package/src/input/Checkbox.tsx +30 -54
  174. package/src/input/ColorInput.tsx +146 -105
  175. package/src/input/ColorPicker.tsx +76 -102
  176. package/src/input/DateInput.tsx +225 -0
  177. package/src/input/Field.tsx +23 -65
  178. package/src/input/File.tsx +76 -98
  179. package/src/input/Hidden.tsx +36 -24
  180. package/src/input/Input.tsx +55 -53
  181. package/src/input/Number.tsx +49 -54
  182. package/src/input/Password.tsx +61 -66
  183. package/src/input/Radio.tsx +28 -37
  184. package/src/input/RadioGroup.tsx +30 -25
  185. package/src/input/{Range.tsx → RangeSlider.tsx} +81 -109
  186. package/src/input/Search.tsx +64 -77
  187. package/src/input/Slider.tsx +80 -109
  188. package/src/input/Switch.tsx +39 -53
  189. package/src/input/Textarea.tsx +72 -59
  190. package/src/internal/ErrorIcon.tsx +22 -21
  191. package/src/internal/FieldWrapper.tsx +33 -23
  192. package/src/internal/InputWrapper.tsx +132 -143
  193. package/src/ranger/index.tsx +37 -117
  194. package/src/ranger/utils.ts +12 -11
  195. package/src/select/AutoComplete.tsx +113 -123
  196. package/src/select/DualList.tsx +218 -204
  197. package/src/select/List.tsx +130 -97
  198. package/src/select/Options.tsx +59 -57
  199. package/src/select/Select.tsx +148 -122
  200. package/src/select/helpers.ts +13 -8
  201. package/src/select/useSelect.tsx +110 -127
  202. package/src/types/index.ts +76 -45
  203. package/src/types/schema.ts +97 -40
  204. package/src/utils/eventHandlers.ts +24 -26
  205. package/src/utils/getColor.ts +9 -8
  206. package/src/utils/getProps.ts +47 -0
  207. package/src/utils/index.ts +1 -0
  208. package/dist/cjs/input/ArrayInput.module.css +0 -1
  209. package/dist/cjs/input/ColorPicker.module.css +0 -1
  210. package/dist/cjs/input/File.module.css +0 -1
  211. package/dist/cjs/internal/Field.module.css +0 -1
  212. package/dist/esm/input/ArrayInput.module.css +0 -1
  213. package/dist/esm/input/ColorPicker.module.css +0 -1
  214. package/dist/esm/input/File.module.css +0 -1
  215. package/dist/esm/internal/Field.module.css +0 -1
@@ -1,10 +1,15 @@
1
- /// <reference types="react" />
2
- import { type RefProp, type TestProps } from "@react-fabric/core/dist/types/types";
1
+ import type { ChildNode, NestedKeys, RefProp, TestProps } from "@react-fabric/core/dist/types/types";
3
2
  export interface InputProps<V = string> extends TestProps {
3
+ name?: string;
4
+ autoFocus?: boolean;
4
5
  /**
5
6
  * value
6
7
  */
7
8
  value?: V;
9
+ /**
10
+ * default value
11
+ */
12
+ defaultValue?: V;
8
13
  /**
9
14
  * change handler
10
15
  */
@@ -20,55 +25,44 @@ export interface InputProps<V = string> extends TestProps {
20
25
  /**
21
26
  * on enter press callback
22
27
  */
23
- onEnterPressed?: React.KeyboardEventHandler;
28
+ onEnterPressed?: React.KeyboardEventHandler<HTMLInputElement>;
29
+ placeholder?: string;
30
+ disabled?: boolean;
31
+ readOnly?: boolean;
24
32
  /**
25
- * input name
33
+ * show clear button
26
34
  */
35
+ allowClear?: boolean;
36
+ }
37
+ export interface WrapperProps {
27
38
  name?: string;
28
39
  /**
29
40
  * input label
30
41
  */
31
42
  label?: string;
32
43
  /**
33
- * input placeholder
44
+ * required
34
45
  */
35
- placeholder?: string;
46
+ required?: boolean;
47
+ disabled?: boolean;
36
48
  /**
37
49
  * append to label end
38
50
  */
39
- appendLabel?: JSX.Element | string | number | boolean;
51
+ appendLabel?: React.ReactNode;
40
52
  /**
41
53
  *
42
54
  */
43
- decorateStart?: JSX.Element | string | number | boolean;
55
+ decorateStart?: React.ReactNode;
44
56
  /**
45
57
  *
46
58
  */
47
- decorateEnd?: JSX.Element | string | number | boolean;
59
+ decorateEnd?: React.ReactNode;
60
+ decorateEndShowWhenEmpty?: boolean;
61
+ decorateEndHideWhenEmpty?: boolean;
48
62
  /**
49
63
  * info label at bottom
50
64
  */
51
- info?: string;
52
- /**
53
- * required
54
- */
55
- required?: boolean;
56
- /**
57
- * disabled input
58
- */
59
- disabled?: boolean;
60
- /**
61
- * read-only input
62
- */
63
- readOnly?: boolean;
64
- /**
65
- * auto focus when rendered
66
- */
67
- autoFocus?: boolean;
68
- /**
69
- * show clear button
70
- */
71
- allowClear?: boolean;
65
+ info?: React.ReactNode;
72
66
  /**
73
67
  * invalid value input
74
68
  */
@@ -88,25 +82,45 @@ export interface InputProps<V = string> extends TestProps {
88
82
  /**
89
83
  * label width for inline
90
84
  */
91
- labelWidth?: string;
85
+ labelWidth?: string | number;
86
+ /**
87
+ * remove the outline borders
88
+ */
89
+ borderless?: boolean;
92
90
  }
93
- export interface BaseSelectProps<T> extends RefProp<HTMLInputElement>, Omit<InputProps, "value" | "onChange"> {
91
+ export interface BaseSelectProps<T extends AnyObject = string> {
92
+ /**
93
+ * open dropdown by default
94
+ */
95
+ defaultOpen?: boolean;
96
+ /**
97
+ * hide dropdown handle
98
+ */
99
+ hideHandle?: boolean;
94
100
  /**
95
101
  * list options
96
102
  */
97
- options?: T[];
103
+ options: T[];
98
104
  /**
99
105
  * group by property name
100
106
  */
101
- groupProperty?: keyof T;
107
+ groupProperty?: NestedKeys<T>;
102
108
  /**
103
109
  * label property name
104
110
  */
105
- labelProperty?: keyof T;
111
+ labelProperty?: NestedKeys<T>;
112
+ /**
113
+ * value property name
114
+ */
115
+ valueProperty?: NestedKeys<T>;
116
+ /**
117
+ * value property name
118
+ */
119
+ infoProperty?: NestedKeys<T>;
106
120
  /**
107
121
  * value property name
108
122
  */
109
- valueProperty?: keyof T;
123
+ sortProperty?: NestedKeys<T> | true;
110
124
  /**
111
125
  * searchable list
112
126
  */
@@ -115,6 +129,10 @@ export interface BaseSelectProps<T> extends RefProp<HTMLInputElement>, Omit<Inpu
115
129
  * allow create item
116
130
  */
117
131
  allowCreate?: boolean;
132
+ /**
133
+ * empty list display
134
+ */
135
+ emptyDisplay?: ChildNode;
118
136
  /**
119
137
  * create new item object
120
138
  */
@@ -126,17 +144,18 @@ export interface BaseSelectProps<T> extends RefProp<HTMLInputElement>, Omit<Inpu
126
144
  /**
127
145
  * item renderer
128
146
  */
129
- renderer?: (option: T) => React.ReactNode;
147
+ renderer?: (option: T) => ChildNode;
130
148
  /**
131
149
  * item matcher
132
150
  */
133
151
  matcher?: (option: T, query: string) => boolean;
134
152
  }
135
- export type SelectProps<T> = BaseSelectProps<T> & ({
153
+ type BaseSelectType<T> = BaseSelectProps<T> & Omit<InputProps, "value" | "onChange"> & WrapperProps & RefProp<HTMLInputElement>;
154
+ export type SelectProps<T> = BaseSelectType<T> & ({
136
155
  /**
137
156
  * is multiple selection
138
157
  */
139
- multiple?: never | false;
158
+ multiple?: false;
140
159
  /**
141
160
  * selected value
142
161
  */
@@ -167,3 +186,18 @@ export type SelectProps<T> = BaseSelectProps<T> & ({
167
186
  */
168
187
  onChange?: (value?: string[]) => void;
169
188
  });
189
+ export type DualSelectProps<T> = BaseSelectType<T> & {
190
+ /**
191
+ * selected value
192
+ */
193
+ value?: string[];
194
+ /**
195
+ * select handler
196
+ */
197
+ onSelect?: (option: T[]) => void;
198
+ /**
199
+ * change handler
200
+ */
201
+ onChange?: (value?: string[]) => void;
202
+ };
203
+ export {};
@@ -1,59 +1,105 @@
1
- interface BaseSchemaDef {
1
+ import type { ChildNode } 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
33
  defaultValue?: AnyObject;
8
34
  }
9
- interface SchemaDef extends BaseSchemaDef {
10
- datatype: "text" | "color";
35
+ export interface DefaultSchema extends BaseSchema {
36
+ datatype: DATA_TYPES.TEXT | DATA_TYPES.COLOR;
11
37
  }
12
- interface BooleanSchema extends BaseSchemaDef {
13
- datatype: "boolean";
14
- defaultValue?: boolean;
38
+ export interface BooleanSchema extends BaseSchema {
39
+ datatype: DATA_TYPES.BOOL;
15
40
  }
16
- interface StringSchema extends BaseSchemaDef {
17
- datatype: "string";
18
- options?: string[];
41
+ export interface StringSchema extends BaseSchema {
42
+ datatype: DATA_TYPES.STRING;
19
43
  regex?: string;
20
- identifierType?: string;
44
+ options?: string[];
45
+ optionList?: string;
46
+ allowCustom?: boolean;
21
47
  }
22
- interface RangeSchema extends BaseSchemaDef {
23
- datatype: "range";
48
+ export interface RangeSchema extends BaseSchema {
49
+ datatype: DATA_TYPES.RANGE;
24
50
  min?: number;
25
51
  max?: number;
26
52
  step?: number;
27
- defaultValue?: [number, number];
28
53
  }
29
- interface NumberSchema extends BaseSchemaDef {
30
- datatype: "number";
31
- min?: number;
32
- max?: number;
33
- step?: number;
34
- defaultValue?: number;
54
+ export interface DateSchema extends BaseSchema {
55
+ datatype: DATA_TYPES.DATE | DATA_TYPES.DATETIME;
56
+ min?: DateLike;
57
+ max?: DateLike;
35
58
  }
36
- interface DecimalSchema extends BaseSchemaDef {
37
- datatype: "decimal";
59
+ export interface NumberSchema extends BaseSchema {
60
+ datatype: DATA_TYPES.NUMBER;
38
61
  min?: number;
39
62
  max?: number;
40
63
  step?: number;
41
- defaultValue?: number;
42
64
  }
43
- export interface FileSchema extends BaseSchemaDef {
44
- datatype: "file";
65
+ export interface FileSchema extends BaseSchema {
66
+ datatype: DATA_TYPES.FILE;
45
67
  accept?: string;
46
68
  }
47
- export interface AvatarSchema extends BaseSchemaDef {
48
- datatype: "avatar";
69
+ export interface AvatarSchema extends BaseSchema {
70
+ datatype: DATA_TYPES.AVATAR;
49
71
  multiple?: false;
50
72
  }
51
- export type SchemaType = SchemaDef | BooleanSchema | StringSchema | RangeSchema | NumberSchema | DecimalSchema | FileSchema | AvatarSchema;
52
- export interface ChildSchema extends BaseSchemaDef {
53
- datatype: "schema";
73
+ export type SchemaType = (DefaultSchema & ValueType) | (BooleanSchema & ValueType) | (StringSchema & ValueType) | (RangeSchema & ValueType) | (DateSchema & ValueType) | (NumberSchema & ValueType) | (FileSchema & ValueType) | (AvatarSchema & ValueType);
74
+ export interface ChildSchema extends BaseSchema {
75
+ datatype: DATA_TYPES.SCHEMA;
54
76
  inline?: boolean;
55
77
  schema: SchemaType[];
56
- defaultValue?: never;
57
78
  }
58
- export type FormSchema = SchemaType | ChildSchema;
79
+ export type SchemaDef = SchemaType | (ChildSchema & ValueType);
80
+ export type FormSchema = SchemaDef[];
81
+ export interface SchemaEditorProps {
82
+ /**
83
+ * default form schema
84
+ */
85
+ schemaDef: FormSchema;
86
+ /**
87
+ * is dynamic schema (allow add/remove)
88
+ */
89
+ dynamic?: boolean;
90
+ /**
91
+ * acceptable list of data types
92
+ */
93
+ acceptableTypes?: DATA_TYPES[];
94
+ /**
95
+ * available option lists in application
96
+ */
97
+ optionLists?: string[];
98
+ /**
99
+ * footer actions
100
+ */
101
+ children?: ChildNode | Array<ChildNode>;
102
+ onChange?: (schema: FormSchema) => void;
103
+ onSubmit?: (schema: FormSchema) => void;
104
+ }
59
105
  export {};
@@ -1,11 +1,11 @@
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 function useHandleEnter<T extends HTMLElement = HTMLInputElement>(callback?: (e: KeyboardEvent<T>) => void, { stopPropagation, preventDefault }?: {
4
4
  stopPropagation?: boolean;
5
5
  preventDefault?: boolean;
6
- }) => (e: KeyboardEvent) => false | undefined;
6
+ }): (e: KeyboardEvent<T>) => false | undefined;
7
7
  /** ***************** common handler for mouse primary click *******************/
8
- export declare const handleClick: (callback?: (e: MouseEvent) => void, { stopPropagation, preventDefault, }?: {
8
+ export declare function handleClick(callback?: (e: MouseEvent) => void, { stopPropagation, preventDefault }?: {
9
9
  stopPropagation?: boolean;
10
10
  preventDefault?: boolean;
11
- }) => (e: MouseEvent) => false | undefined;
11
+ }): (e: MouseEvent) => false | undefined;
@@ -1,4 +1,4 @@
1
- export declare const getColor: (color?: string) => string | undefined;
2
- export declare const getBgClass: (bg: string) => string | undefined;
3
- export declare const getColorClass: (color: string) => string | undefined;
4
- export declare const getBorderClass: (color: string) => string | undefined;
1
+ export declare function getColor(color?: string): string | undefined;
2
+ export declare function getBgClass(bg: string): string | undefined;
3
+ export declare function getColorClass(color: string): string | undefined;
4
+ export declare function getBorderClass(color: string): string | undefined;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * React Fabric
3
+ * @version 1.0.0
4
+ * @license MIT
5
+ * @copyright 2024 Adarsh Pastakia
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in all
15
+ * copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ * SOFTWARE.
24
+ */
25
+ import type { WrapperProps } from "../types";
26
+ export declare function getWrapperProps<T extends WrapperProps & KeyValue>(props: T): WrapperProps;
@@ -1,2 +1,3 @@
1
1
  export * from "./eventHandlers";
2
2
  export * from "./getColor";
3
+ export * from "./getProps";
package/package.json CHANGED
@@ -1,19 +1,21 @@
1
1
  {
2
2
  "name": "@react-fabric/form",
3
- "version": "1.0.0-beta.9",
3
+ "version": "1.0.2",
4
4
  "description": "RUF: Form package",
5
5
  "author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
6
6
  "license": "MIT",
7
- "repository": "https://github.com/adarshpastakia/react-ui-framework/tree/main/packages/form",
7
+ "repository": "https://github.com/adarshpastakia/react-fabric/tree/main/packages/form",
8
8
  "source": "src/index.ts",
9
9
  "main": "dist/cjs/index.js",
10
10
  "module": "dist/esm/index.js",
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,8 +24,6 @@
22
24
  "registry": "https://registry.npmjs.org/"
23
25
  },
24
26
  "scripts": {
25
- "makelink": "yarn link",
26
- "removelink": "yarn unlink",
27
27
  "prebuild": "rm -rf ./dist",
28
28
  "build:dts": "tsc -p ./tsconfig.build.json",
29
29
  "build:rollup": "rollup -c ../../rollup.config.mjs",
@@ -33,32 +33,32 @@
33
33
  "watch": "npm-run-all -p watch:rollup watch:dts"
34
34
  },
35
35
  "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.9",
43
- "@react-fabric/utilities": "^1.0.0-beta.9",
44
- "classnames": "^2.5.1",
45
- "color": "^4.2.3",
46
- "react-color": "^2.19.3",
47
- "react-hook-form": "^7.52.1"
36
+ "@dnd-kit/abstract": "~0.5.0",
37
+ "@dnd-kit/react": "~0.5.0",
38
+ "@faker-js/faker": "10.6.0",
39
+ "@floating-ui/react": "~0.27.20",
40
+ "@hookform/resolvers": "~5.9.1",
41
+ "@react-fabric/core": "^1.0.2",
42
+ "@react-fabric/date": "^1.0.2",
43
+ "@react-fabric/utilities": "^1.0.2",
44
+ "@tanstack/react-form": "~1.33.3",
45
+ "chroma-js": "~3.2.0",
46
+ "react-color": "~2.19.3",
47
+ "react-hook-form": "~7.86.0"
48
48
  },
49
49
  "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"
50
+ "axios": "^1.20.0",
51
+ "i18next": "~26.3.6",
52
+ "react": "~19.3.0",
53
+ "react-dom": "~19.3.0",
54
+ "react-i18next": "~17.0.11"
54
55
  },
55
56
  "devDependencies": {
56
- "@types/axios": "^0.14.0",
57
- "@types/react-color": "^3.0.12"
57
+ "@types/react-color": "~3.0.13"
58
58
  },
59
59
  "engines": {
60
- "node": ">=18.12.0",
61
- "npm": ">=8.19.0"
60
+ "node": ">=24.0.0",
61
+ "npm": ">=11.0.0"
62
62
  },
63
- "gitHead": "3dde23444bcebf68c30198af5c2fef55572da38f"
63
+ "gitHead": "b9fc477b5b3a13b782977bf17762027f376ac30e"
64
64
  }
@@ -21,62 +21,93 @@
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 { Badge, Button, Icon, ProgressBar, Tooltip } from "@react-fabric/core";
25
+ import { FileUtil, Format, isObject, isString } from "@react-fabric/utilities";
26
26
  import { Fragment } from "react";
27
- import { type UploadHandler, useFileUploader } from "../hooks/useFileUploader";
27
+ import { useTranslation } from "react-i18next";
28
+ import { useFileUploader, type UploadHandler } from "../hooks/useFileUploader";
28
29
  import { Field } from "../input/Field";
29
30
  import { HiddenInput } from "../input/Hidden";
30
- import { type FileSchema } from "../types/schema";
31
+ import { type FileSchema, type ValueType } from "../types/schema";
31
32
 
32
- export const FileField = ({
33
+ interface ErrorObject {
34
+ key: string;
35
+ values: Record<string, string>;
36
+ }
37
+
38
+ export function FileField({
33
39
  uploadHandler,
34
40
  inline,
35
41
  label,
36
42
  accept,
37
- multiple = false,
38
43
  value,
44
+ onChange,
45
+ multiple,
46
+ error,
47
+ invalid,
39
48
  ...rest
40
- }: Partial<FileSchema> & {
41
- value?: AnyObject;
49
+ }: Partial<FileSchema & ValueType> & {
50
+ value?: never;
42
51
  inline?: boolean;
52
+ invalid?: boolean;
53
+ error?: AnyObject;
54
+ onChange?: (value: AnyObject) => void;
43
55
  fileUrl?: (path: string) => string;
44
56
  uploadHandler: UploadHandler;
45
- }) => {
46
- const { pending, files, list, upload, remove } = useFileUploader(
57
+ }) {
58
+ const { t } = useTranslation();
59
+ const { pending, files, upload, remove } = useFileUploader(
47
60
  async (data, config) => await uploadHandler?.(data, config),
48
61
  value,
49
- multiple,
62
+ { multiple, onChange },
50
63
  );
51
64
 
52
65
  return (
53
66
  <Fragment>
54
- <Field plain inline={inline} label={label} className="inline-block">
55
- <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>
67
+ <Field plain inline={inline} label={label}>
68
+ <HiddenInput hiddenValue={multiple ? files : files?.[0]} {...rest} />
76
69
  </Field>
70
+ <Tooltip
71
+ color="danger"
72
+ content={
73
+ isObject<ErrorObject>(error)
74
+ ? t(
75
+ error.key,
76
+ isObject(error.values)
77
+ ? {
78
+ ...error.values,
79
+ label: t(error.values.label ?? "form:badkey", error.values.path),
80
+ }
81
+ : {},
82
+ )
83
+ : isString(error)
84
+ ? error
85
+ : ""
86
+ }
87
+ disabled={!error}
88
+ >
89
+ <Button
90
+ altIcon={pending > 0 ? <Badge inline>{pending}</Badge> : undefined}
91
+ color={invalid ? "danger" : undefined}
92
+ variant={invalid ? "soft" : undefined}
93
+ data-ref="filebtn"
94
+ >
95
+ <Fragment>
96
+ <span>Add file</span>
97
+ <input
98
+ type="file"
99
+ accept={accept}
100
+ multiple={multiple}
101
+ className="absolute inset-0 opacity-0 z-5"
102
+ onChange={(e) => [upload(e.target.files), (e.target.value = "")]}
103
+ />
104
+ </Fragment>
105
+ </Button>
106
+ </Tooltip>
77
107
  <br />
78
108
  <div className="bg-alternate">
79
109
  {files.map((file, idx) => (
110
+ // eslint-disable-next-line @eslint-react/no-array-index-key
80
111
  <div key={idx} className="px-2 py-1">
81
112
  <div className="flex flex-nowrap gap-1 items-start">
82
113
  <div className="flex-1 truncate pe-2">
@@ -86,37 +117,23 @@ export const FileField = ({
86
117
  <span className="text-xs px-1">{Format.bytes(file.size)}</span>
87
118
  </div>
88
119
  <div className="flex-initial truncate px-2">
89
- {file.error && (
90
- <span className="text-danger-600">{file.error}</span>
91
- )}
120
+ {file.error && <span className="text-danger-600">{file.error}</span>}
92
121
  </div>
93
122
  {file.progress && (
94
- <Icon
95
- icon="mdi mdi-stop-circle"
96
- bg="danger"
97
- color="white"
98
- size="sm"
99
- className="p-[2px]"
100
- aria-label="abort"
101
- onClick={() => file.abort?.()}
102
- />
123
+ <button type="button" className="size-fit leading-0 cursor-pointer" onClick={() => file.abort?.()}>
124
+ <Icon icon="icon-[mdi--stop]" bg="danger" color="white" size="sm" className="p-0.5" aria-label="abort" />
125
+ </button>
103
126
  )}
104
127
  {!file.progress && (
105
- <Icon
106
- icon="mdi mdi-trash-can"
107
- color="danger"
108
- size="sm"
109
- aria-label="remove"
110
- onClick={() => remove(file.key)}
111
- />
128
+ <button type="button" className="size-fit leading-0 cursor-pointer" onClick={() => remove(file.key)}>
129
+ <Icon icon="icon-[mdi--trash-can-outline]" color="danger" size="sm" aria-label="remove" />
130
+ </button>
112
131
  )}
113
132
  </div>
114
- {file.progress && (
115
- <ProgressBar animate value={file.progress * 100} size="xxs" />
116
- )}
133
+ {file.progress && <ProgressBar animate value={file.progress * 100} size="xxs" />}
117
134
  </div>
118
135
  ))}
119
136
  </div>
120
137
  </Fragment>
121
138
  );
122
- };
139
+ }