@refinedev/antd 5.0.0

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 (288) hide show
  1. package/CHANGELOG.md +1689 -0
  2. package/README.md +285 -0
  3. package/dist/components/breadcrumb/index.d.ts +6 -0
  4. package/dist/components/breadcrumb/index.d.ts.map +1 -0
  5. package/dist/components/buttons/clone/index.d.ts +11 -0
  6. package/dist/components/buttons/clone/index.d.ts.map +1 -0
  7. package/dist/components/buttons/create/index.d.ts +11 -0
  8. package/dist/components/buttons/create/index.d.ts.map +1 -0
  9. package/dist/components/buttons/delete/index.d.ts +10 -0
  10. package/dist/components/buttons/delete/index.d.ts.map +1 -0
  11. package/dist/components/buttons/edit/index.d.ts +11 -0
  12. package/dist/components/buttons/edit/index.d.ts.map +1 -0
  13. package/dist/components/buttons/export/index.d.ts +10 -0
  14. package/dist/components/buttons/export/index.d.ts.map +1 -0
  15. package/dist/components/buttons/import/index.d.ts +11 -0
  16. package/dist/components/buttons/import/index.d.ts.map +1 -0
  17. package/dist/components/buttons/index.d.ts +12 -0
  18. package/dist/components/buttons/index.d.ts.map +1 -0
  19. package/dist/components/buttons/list/index.d.ts +11 -0
  20. package/dist/components/buttons/list/index.d.ts.map +1 -0
  21. package/dist/components/buttons/refresh/index.d.ts +10 -0
  22. package/dist/components/buttons/refresh/index.d.ts.map +1 -0
  23. package/dist/components/buttons/save/index.d.ts +10 -0
  24. package/dist/components/buttons/save/index.d.ts.map +1 -0
  25. package/dist/components/buttons/show/index.d.ts +11 -0
  26. package/dist/components/buttons/show/index.d.ts.map +1 -0
  27. package/dist/components/buttons/types.d.ts +24 -0
  28. package/dist/components/buttons/types.d.ts.map +1 -0
  29. package/dist/components/crud/create/index.d.ts +10 -0
  30. package/dist/components/crud/create/index.d.ts.map +1 -0
  31. package/dist/components/crud/edit/index.d.ts +10 -0
  32. package/dist/components/crud/edit/index.d.ts.map +1 -0
  33. package/dist/components/crud/index.d.ts +6 -0
  34. package/dist/components/crud/index.d.ts.map +1 -0
  35. package/dist/components/crud/list/index.d.ts +10 -0
  36. package/dist/components/crud/list/index.d.ts.map +1 -0
  37. package/dist/components/crud/show/index.d.ts +10 -0
  38. package/dist/components/crud/show/index.d.ts.map +1 -0
  39. package/dist/components/crud/types.d.ts +10 -0
  40. package/dist/components/crud/types.d.ts.map +1 -0
  41. package/dist/components/fields/boolean/index.d.ts +9 -0
  42. package/dist/components/fields/boolean/index.d.ts.map +1 -0
  43. package/dist/components/fields/date/index.d.ts +9 -0
  44. package/dist/components/fields/date/index.d.ts.map +1 -0
  45. package/dist/components/fields/email/index.d.ts +10 -0
  46. package/dist/components/fields/email/index.d.ts.map +1 -0
  47. package/dist/components/fields/file/index.d.ts +9 -0
  48. package/dist/components/fields/file/index.d.ts.map +1 -0
  49. package/dist/components/fields/image/index.d.ts +9 -0
  50. package/dist/components/fields/image/index.d.ts.map +1 -0
  51. package/dist/components/fields/index.d.ts +12 -0
  52. package/dist/components/fields/index.d.ts.map +1 -0
  53. package/dist/components/fields/markdown/index.d.ts +9 -0
  54. package/dist/components/fields/markdown/index.d.ts.map +1 -0
  55. package/dist/components/fields/number/index.d.ts +9 -0
  56. package/dist/components/fields/number/index.d.ts.map +1 -0
  57. package/dist/components/fields/tag/index.d.ts +9 -0
  58. package/dist/components/fields/tag/index.d.ts.map +1 -0
  59. package/dist/components/fields/text/index.d.ts +9 -0
  60. package/dist/components/fields/text/index.d.ts.map +1 -0
  61. package/dist/components/fields/types.d.ts +20 -0
  62. package/dist/components/fields/types.d.ts.map +1 -0
  63. package/dist/components/fields/url/index.d.ts +10 -0
  64. package/dist/components/fields/url/index.d.ts.map +1 -0
  65. package/dist/components/index.d.ts +13 -0
  66. package/dist/components/index.d.ts.map +1 -0
  67. package/dist/components/layout/header/index.d.ts +4 -0
  68. package/dist/components/layout/header/index.d.ts.map +1 -0
  69. package/dist/components/layout/index.d.ts +4 -0
  70. package/dist/components/layout/index.d.ts.map +1 -0
  71. package/dist/components/layout/sider/index.d.ts +4 -0
  72. package/dist/components/layout/sider/index.d.ts.map +1 -0
  73. package/dist/components/layout/sider/styles.d.ts +3 -0
  74. package/dist/components/layout/sider/styles.d.ts.map +1 -0
  75. package/dist/components/layout/title/index.d.ts +4 -0
  76. package/dist/components/layout/title/index.d.ts.map +1 -0
  77. package/dist/components/layout/types.d.ts +3 -0
  78. package/dist/components/layout/types.d.ts.map +1 -0
  79. package/dist/components/pageHeader/index.d.ts +5 -0
  80. package/dist/components/pageHeader/index.d.ts.map +1 -0
  81. package/dist/components/pages/auth/components/forgotPassword/index.d.ts +12 -0
  82. package/dist/components/pages/auth/components/forgotPassword/index.d.ts.map +1 -0
  83. package/dist/components/pages/auth/components/index.d.ts +5 -0
  84. package/dist/components/pages/auth/components/index.d.ts.map +1 -0
  85. package/dist/components/pages/auth/components/login/index.d.ts +12 -0
  86. package/dist/components/pages/auth/components/login/index.d.ts.map +1 -0
  87. package/dist/components/pages/auth/components/register/index.d.ts +12 -0
  88. package/dist/components/pages/auth/components/register/index.d.ts.map +1 -0
  89. package/dist/components/pages/auth/components/styles.d.ts +5 -0
  90. package/dist/components/pages/auth/components/styles.d.ts.map +1 -0
  91. package/dist/components/pages/auth/components/updatePassword/index.d.ts +12 -0
  92. package/dist/components/pages/auth/components/updatePassword/index.d.ts.map +1 -0
  93. package/dist/components/pages/auth/index.d.ts +11 -0
  94. package/dist/components/pages/auth/index.d.ts.map +1 -0
  95. package/dist/components/pages/error/index.d.ts +10 -0
  96. package/dist/components/pages/error/index.d.ts.map +1 -0
  97. package/dist/components/pages/index.d.ts +7 -0
  98. package/dist/components/pages/index.d.ts.map +1 -0
  99. package/dist/components/pages/login/index.d.ts +15 -0
  100. package/dist/components/pages/login/index.d.ts.map +1 -0
  101. package/dist/components/pages/login/styles.d.ts +6 -0
  102. package/dist/components/pages/login/styles.d.ts.map +1 -0
  103. package/dist/components/pages/ready/index.d.ts +10 -0
  104. package/dist/components/pages/ready/index.d.ts.map +1 -0
  105. package/dist/components/pages/welcome/index.d.ts +6 -0
  106. package/dist/components/pages/welcome/index.d.ts.map +1 -0
  107. package/dist/components/table/components/filterDropdown/index.d.ts +13 -0
  108. package/dist/components/table/components/filterDropdown/index.d.ts.map +1 -0
  109. package/dist/components/table/components/index.d.ts +2 -0
  110. package/dist/components/table/components/index.d.ts.map +1 -0
  111. package/dist/components/table/index.d.ts +2 -0
  112. package/dist/components/table/index.d.ts.map +1 -0
  113. package/dist/components/undoableNotification/index.d.ts +10 -0
  114. package/dist/components/undoableNotification/index.d.ts.map +1 -0
  115. package/dist/definitions/index.d.ts +3 -0
  116. package/dist/definitions/index.d.ts.map +1 -0
  117. package/dist/definitions/table/index.d.ts +10 -0
  118. package/dist/definitions/table/index.d.ts.map +1 -0
  119. package/dist/definitions/upload/index.d.ts +4 -0
  120. package/dist/definitions/upload/index.d.ts.map +1 -0
  121. package/dist/esm/index.js +2 -0
  122. package/dist/esm/index.js.map +1 -0
  123. package/dist/hooks/fields/index.d.ts +4 -0
  124. package/dist/hooks/fields/index.d.ts.map +1 -0
  125. package/dist/hooks/fields/useCheckboxGroup/index.d.ts +24 -0
  126. package/dist/hooks/fields/useCheckboxGroup/index.d.ts.map +1 -0
  127. package/dist/hooks/fields/useRadioGroup/index.d.ts +24 -0
  128. package/dist/hooks/fields/useRadioGroup/index.d.ts.map +1 -0
  129. package/dist/hooks/fields/useSelect/index.d.ts +21 -0
  130. package/dist/hooks/fields/useSelect/index.d.ts.map +1 -0
  131. package/dist/hooks/form/index.d.ts +5 -0
  132. package/dist/hooks/form/index.d.ts.map +1 -0
  133. package/dist/hooks/form/useDrawerForm/index.d.ts +2 -0
  134. package/dist/hooks/form/useDrawerForm/index.d.ts.map +1 -0
  135. package/dist/hooks/form/useDrawerForm/useDrawerForm.d.ts +33 -0
  136. package/dist/hooks/form/useDrawerForm/useDrawerForm.d.ts.map +1 -0
  137. package/dist/hooks/form/useForm.d.ts +31 -0
  138. package/dist/hooks/form/useForm.d.ts.map +1 -0
  139. package/dist/hooks/form/useModalForm/index.d.ts +2 -0
  140. package/dist/hooks/form/useModalForm/index.d.ts.map +1 -0
  141. package/dist/hooks/form/useModalForm/useModalForm.d.ts +39 -0
  142. package/dist/hooks/form/useModalForm/useModalForm.d.ts.map +1 -0
  143. package/dist/hooks/form/useStepsForm/index.d.ts +2 -0
  144. package/dist/hooks/form/useStepsForm/index.d.ts.map +1 -0
  145. package/dist/hooks/form/useStepsForm/useStepsForm.d.ts +35 -0
  146. package/dist/hooks/form/useStepsForm/useStepsForm.d.ts.map +1 -0
  147. package/dist/hooks/import/index.d.ts +18 -0
  148. package/dist/hooks/import/index.d.ts.map +1 -0
  149. package/dist/hooks/index.d.ts +8 -0
  150. package/dist/hooks/index.d.ts.map +1 -0
  151. package/dist/hooks/list/index.d.ts +2 -0
  152. package/dist/hooks/list/index.d.ts.map +1 -0
  153. package/dist/hooks/list/useSimpleList/index.d.ts +2 -0
  154. package/dist/hooks/list/useSimpleList/index.d.ts.map +1 -0
  155. package/dist/hooks/list/useSimpleList/useSimpleList.d.ts +23 -0
  156. package/dist/hooks/list/useSimpleList/useSimpleList.d.ts.map +1 -0
  157. package/dist/hooks/modal/index.d.ts +2 -0
  158. package/dist/hooks/modal/index.d.ts.map +1 -0
  159. package/dist/hooks/modal/useModal/index.d.ts +18 -0
  160. package/dist/hooks/modal/useModal/index.d.ts.map +1 -0
  161. package/dist/hooks/table/index.d.ts +3 -0
  162. package/dist/hooks/table/index.d.ts.map +1 -0
  163. package/dist/hooks/table/useEditableTable/index.d.ts +2 -0
  164. package/dist/hooks/table/useEditableTable/index.d.ts.map +1 -0
  165. package/dist/hooks/table/useEditableTable/useEditableTable.d.ts +28 -0
  166. package/dist/hooks/table/useEditableTable/useEditableTable.d.ts.map +1 -0
  167. package/dist/hooks/table/useTable/index.d.ts +2 -0
  168. package/dist/hooks/table/useTable/index.d.ts.map +1 -0
  169. package/dist/hooks/table/useTable/paginationLink.d.ts +8 -0
  170. package/dist/hooks/table/useTable/paginationLink.d.ts.map +1 -0
  171. package/dist/hooks/table/useTable/useTable.d.ts +18 -0
  172. package/dist/hooks/table/useTable/useTable.d.ts.map +1 -0
  173. package/dist/hooks/useFileUploadState/index.d.ts +7 -0
  174. package/dist/hooks/useFileUploadState/index.d.ts.map +1 -0
  175. package/dist/iife/index.js +56 -0
  176. package/dist/iife/index.js.map +1 -0
  177. package/dist/index.d.ts +6 -0
  178. package/dist/index.d.ts.map +1 -0
  179. package/dist/index.js +2 -0
  180. package/dist/index.js.map +1 -0
  181. package/dist/interfaces/field.d.ts +4 -0
  182. package/dist/interfaces/field.d.ts.map +1 -0
  183. package/dist/interfaces/index.d.ts +19 -0
  184. package/dist/interfaces/index.d.ts.map +1 -0
  185. package/dist/interfaces/upload.d.ts +10 -0
  186. package/dist/interfaces/upload.d.ts.map +1 -0
  187. package/dist/providers/index.d.ts +2 -0
  188. package/dist/providers/index.d.ts.map +1 -0
  189. package/dist/providers/notificationProvider/index.d.ts +3 -0
  190. package/dist/providers/notificationProvider/index.d.ts.map +1 -0
  191. package/dist/reset.css +254 -0
  192. package/package.json +72 -0
  193. package/refine.config.js +604 -0
  194. package/src/assets/styles/reset.css +254 -0
  195. package/src/components/breadcrumb/index.tsx +70 -0
  196. package/src/components/buttons/clone/index.tsx +104 -0
  197. package/src/components/buttons/create/index.tsx +103 -0
  198. package/src/components/buttons/delete/index.tsx +122 -0
  199. package/src/components/buttons/edit/index.tsx +105 -0
  200. package/src/components/buttons/export/index.tsx +32 -0
  201. package/src/components/buttons/import/index.tsx +36 -0
  202. package/src/components/buttons/index.ts +11 -0
  203. package/src/components/buttons/list/index.tsx +122 -0
  204. package/src/components/buttons/refresh/index.tsx +61 -0
  205. package/src/components/buttons/save/index.tsx +32 -0
  206. package/src/components/buttons/show/index.tsx +104 -0
  207. package/src/components/buttons/types.ts +44 -0
  208. package/src/components/crud/create/index.tsx +135 -0
  209. package/src/components/crud/edit/index.tsx +221 -0
  210. package/src/components/crud/index.ts +6 -0
  211. package/src/components/crud/list/index.tsx +105 -0
  212. package/src/components/crud/show/index.tsx +215 -0
  213. package/src/components/crud/types.ts +63 -0
  214. package/src/components/fields/boolean/index.tsx +26 -0
  215. package/src/components/fields/date/index.tsx +33 -0
  216. package/src/components/fields/email/index.tsx +20 -0
  217. package/src/components/fields/file/index.tsx +21 -0
  218. package/src/components/fields/image/index.tsx +17 -0
  219. package/src/components/fields/index.ts +11 -0
  220. package/src/components/fields/markdown/index.tsx +16 -0
  221. package/src/components/fields/number/index.tsx +36 -0
  222. package/src/components/fields/tag/index.tsx +13 -0
  223. package/src/components/fields/text/index.tsx +15 -0
  224. package/src/components/fields/types.ts +49 -0
  225. package/src/components/fields/url/index.tsx +24 -0
  226. package/src/components/index.ts +14 -0
  227. package/src/components/layout/header/index.tsx +37 -0
  228. package/src/components/layout/index.tsx +41 -0
  229. package/src/components/layout/sider/index.tsx +261 -0
  230. package/src/components/layout/sider/styles.ts +9 -0
  231. package/src/components/layout/title/index.tsx +48 -0
  232. package/src/components/layout/types.ts +11 -0
  233. package/src/components/pageHeader/index.tsx +52 -0
  234. package/src/components/pages/auth/components/forgotPassword/index.tsx +167 -0
  235. package/src/components/pages/auth/components/index.tsx +4 -0
  236. package/src/components/pages/auth/components/login/index.tsx +239 -0
  237. package/src/components/pages/auth/components/register/index.tsx +210 -0
  238. package/src/components/pages/auth/components/styles.ts +23 -0
  239. package/src/components/pages/auth/components/updatePassword/index.tsx +158 -0
  240. package/src/components/pages/auth/index.tsx +35 -0
  241. package/src/components/pages/error/index.tsx +77 -0
  242. package/src/components/pages/index.tsx +6 -0
  243. package/src/components/pages/login/index.tsx +172 -0
  244. package/src/components/pages/login/styles.ts +25 -0
  245. package/src/components/pages/ready/index.tsx +96 -0
  246. package/src/components/pages/welcome/index.tsx +87 -0
  247. package/src/components/table/components/filterDropdown/index.tsx +112 -0
  248. package/src/components/table/components/index.ts +1 -0
  249. package/src/components/table/index.ts +1 -0
  250. package/src/components/undoableNotification/index.tsx +46 -0
  251. package/src/definitions/index.ts +2 -0
  252. package/src/definitions/table/index.ts +113 -0
  253. package/src/definitions/upload/index.ts +29 -0
  254. package/src/hooks/fields/index.ts +3 -0
  255. package/src/hooks/fields/useCheckboxGroup/index.ts +85 -0
  256. package/src/hooks/fields/useRadioGroup/index.ts +85 -0
  257. package/src/hooks/fields/useSelect/index.ts +47 -0
  258. package/src/hooks/form/index.ts +17 -0
  259. package/src/hooks/form/useDrawerForm/index.ts +6 -0
  260. package/src/hooks/form/useDrawerForm/useDrawerForm.ts +241 -0
  261. package/src/hooks/form/useForm.ts +168 -0
  262. package/src/hooks/form/useModalForm/index.ts +5 -0
  263. package/src/hooks/form/useModalForm/useModalForm.ts +286 -0
  264. package/src/hooks/form/useStepsForm/index.ts +5 -0
  265. package/src/hooks/form/useStepsForm/useStepsForm.ts +91 -0
  266. package/src/hooks/import/index.tsx +134 -0
  267. package/src/hooks/index.ts +7 -0
  268. package/src/hooks/list/index.ts +1 -0
  269. package/src/hooks/list/useSimpleList/index.ts +1 -0
  270. package/src/hooks/list/useSimpleList/useSimpleList.ts +229 -0
  271. package/src/hooks/modal/index.ts +1 -0
  272. package/src/hooks/modal/useModal/index.tsx +43 -0
  273. package/src/hooks/table/index.ts +2 -0
  274. package/src/hooks/table/useEditableTable/index.ts +1 -0
  275. package/src/hooks/table/useEditableTable/useEditableTable.ts +87 -0
  276. package/src/hooks/table/useTable/index.ts +1 -0
  277. package/src/hooks/table/useTable/paginationLink.tsx +27 -0
  278. package/src/hooks/table/useTable/useTable.ts +267 -0
  279. package/src/hooks/useFileUploadState/index.ts +34 -0
  280. package/src/index.tsx +11 -0
  281. package/src/interfaces/field.ts +3 -0
  282. package/src/interfaces/index.ts +23 -0
  283. package/src/interfaces/upload.ts +9 -0
  284. package/src/providers/index.ts +1 -0
  285. package/src/providers/notificationProvider/index.tsx +41 -0
  286. package/src/types/index.d.ts +4 -0
  287. package/src/types/sunflower.d.ts +86 -0
  288. package/tsconfig.json +28 -0
@@ -0,0 +1,241 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { UseFormConfig } from "sunflower-antd";
3
+ import { FormInstance, FormProps, DrawerProps, ButtonProps } from "antd";
4
+ import {
5
+ useMutationMode,
6
+ useTranslate,
7
+ useWarnAboutChange,
8
+ UseFormProps as UseFormPropsCore,
9
+ HttpError,
10
+ LiveModeProps,
11
+ BaseRecord,
12
+ FormWithSyncWithLocationParams,
13
+ BaseKey,
14
+ useResource,
15
+ useParsed,
16
+ useGo,
17
+ } from "@refinedev/core";
18
+
19
+ import { useForm, UseFormProps, UseFormReturnType } from "../useForm";
20
+ import { DeleteButtonProps } from "../../../components";
21
+ import React from "react";
22
+
23
+ export interface UseDrawerFormConfig extends UseFormConfig {
24
+ action: "show" | "edit" | "create" | "clone";
25
+ }
26
+
27
+ export type UseDrawerFormProps<
28
+ TData extends BaseRecord = BaseRecord,
29
+ TError extends HttpError = HttpError,
30
+ TVariables = {},
31
+ > = UseFormPropsCore<TData, TError, TVariables> &
32
+ UseFormProps<TData, TError, TVariables> &
33
+ UseDrawerFormConfig &
34
+ LiveModeProps &
35
+ FormWithSyncWithLocationParams;
36
+
37
+ export type UseDrawerFormReturnType<
38
+ TData extends BaseRecord = BaseRecord,
39
+ TError extends HttpError = HttpError,
40
+ TVariables = {},
41
+ > = UseFormReturnType<TData, TError, TVariables> & {
42
+ formProps: FormProps<TVariables> & {
43
+ form: FormInstance<TVariables>;
44
+ };
45
+ show: (id?: BaseKey) => void;
46
+ close: () => void;
47
+ drawerProps: DrawerProps;
48
+ saveButtonProps: ButtonProps;
49
+ deleteButtonProps: DeleteButtonProps;
50
+ formLoading: boolean;
51
+ };
52
+
53
+ /**
54
+ * `useDrawerForm` hook allows you to manage a form within a drawer. It returns Ant Design {@link https://ant.design/components/form/ Form} and {@link https://ant.design/components/drawer/ Drawer} components props.
55
+ *
56
+ * @see {@link https://refine.dev/docs/ui-frameworks/antd/hooks/form/useDrawerForm} for more details.
57
+ *
58
+ * @typeParam TData - Result data of the query extends {@link https://refine.dev/docs/api-references/interfaceReferences#baserecord `BaseRecord`}
59
+ * @typeParam TError - Custom error object that extends {@link https://refine.dev/docs/api-references/interfaceReferences#httperror `HttpError`}
60
+ * @typeParam TVariables - Values for params. default `{}`
61
+ *
62
+ *
63
+ */
64
+
65
+ export const useDrawerForm = <
66
+ TData extends BaseRecord = BaseRecord,
67
+ TError extends HttpError = HttpError,
68
+ TVariables = {},
69
+ >({
70
+ mutationMode: mutationModeProp,
71
+ syncWithLocation,
72
+ ...rest
73
+ }: UseDrawerFormProps<TData, TError, TVariables>): UseDrawerFormReturnType<
74
+ TData,
75
+ TError,
76
+ TVariables
77
+ > => {
78
+ const initiallySynced = React.useRef(false);
79
+
80
+ const useFormProps = useForm<TData, TError, TVariables>({
81
+ ...rest,
82
+ mutationMode: mutationModeProp,
83
+ });
84
+
85
+ const { form, formProps, formLoading, mutationResult, id, setId } =
86
+ useFormProps;
87
+
88
+ const { resource, action: actionFromParams } = useResource(rest.resource);
89
+
90
+ const parsed = useParsed();
91
+ const go = useGo();
92
+
93
+ const action = rest.action ?? actionFromParams ?? "";
94
+
95
+ const syncingId =
96
+ typeof syncWithLocation === "object" && syncWithLocation.syncId;
97
+
98
+ const syncWithLocationKey =
99
+ typeof syncWithLocation === "object" && "key" in syncWithLocation
100
+ ? syncWithLocation.key
101
+ : resource && action && syncWithLocation
102
+ ? `drawer-${resource?.identifier ?? resource?.name}-${action}`
103
+ : undefined;
104
+
105
+ const [open, setOpen] = useState(false);
106
+
107
+ React.useEffect(() => {
108
+ if (initiallySynced.current === false && syncWithLocationKey) {
109
+ const openStatus = parsed?.params?.[syncWithLocationKey]?.open;
110
+ if (typeof openStatus === "boolean") {
111
+ setOpen(openStatus);
112
+ } else if (typeof openStatus === "string") {
113
+ setOpen(openStatus === "true");
114
+ }
115
+
116
+ if (syncingId) {
117
+ const idFromParams = parsed?.params?.[syncWithLocationKey]?.id;
118
+ if (idFromParams) {
119
+ setId?.(idFromParams);
120
+ }
121
+ }
122
+
123
+ initiallySynced.current = true;
124
+ }
125
+ }, [syncWithLocationKey, parsed, syncingId, setId]);
126
+
127
+ React.useEffect(() => {
128
+ if (initiallySynced.current === true) {
129
+ if (open && syncWithLocationKey) {
130
+ go({
131
+ query: {
132
+ [syncWithLocationKey]: {
133
+ ...parsed?.params?.[syncWithLocationKey],
134
+ open: true,
135
+ ...(syncingId && id && { id }),
136
+ },
137
+ },
138
+ options: { keepQuery: true },
139
+ type: "replace",
140
+ });
141
+ } else if (syncWithLocationKey && !open) {
142
+ go({
143
+ query: {
144
+ [syncWithLocationKey]: undefined,
145
+ },
146
+ options: { keepQuery: true },
147
+ type: "replace",
148
+ });
149
+ }
150
+ }
151
+ }, [id, open, syncWithLocationKey, syncingId]);
152
+
153
+ const translate = useTranslate();
154
+
155
+ const { warnWhen, setWarnWhen } = useWarnAboutChange();
156
+
157
+ const { mutationMode: mutationModeContext } = useMutationMode();
158
+ const mutationMode = mutationModeProp ?? mutationModeContext;
159
+
160
+ const {
161
+ isLoading: isLoadingMutation,
162
+ isSuccess: isSuccessMutation,
163
+ reset: resetMutation,
164
+ } = mutationResult ?? {};
165
+
166
+ useEffect(() => {
167
+ if (open && mutationMode === "pessimistic") {
168
+ if (isSuccessMutation && !isLoadingMutation) {
169
+ setOpen(false);
170
+ resetMutation?.();
171
+ }
172
+ }
173
+ }, [isSuccessMutation, isLoadingMutation]);
174
+
175
+ const saveButtonProps = {
176
+ disabled: formLoading,
177
+ onClick: () => {
178
+ form?.submit();
179
+ if (!(mutationMode === "pessimistic")) {
180
+ setOpen(false);
181
+ }
182
+ },
183
+ loading: formLoading,
184
+ };
185
+
186
+ const deleteButtonProps = {
187
+ recordItemId: id,
188
+ onSuccess: () => {
189
+ setId?.(undefined);
190
+ setOpen(false);
191
+ },
192
+ };
193
+
194
+ const handleClose = useCallback(() => {
195
+ if (warnWhen) {
196
+ const warnWhenConfirm = window.confirm(
197
+ translate(
198
+ "warnWhenUnsavedChanges",
199
+ "Are you sure you want to leave? You have unsaved changes.",
200
+ ),
201
+ );
202
+
203
+ if (warnWhenConfirm) {
204
+ setWarnWhen(false);
205
+ } else {
206
+ return;
207
+ }
208
+ }
209
+
210
+ setOpen(false);
211
+ setId?.(undefined);
212
+ }, [warnWhen]);
213
+
214
+ const handleShow = useCallback((id?: BaseKey) => {
215
+ setId?.(id);
216
+
217
+ setOpen(true);
218
+ }, []);
219
+
220
+ return {
221
+ ...useFormProps,
222
+ show: handleShow,
223
+ close: handleClose,
224
+ formProps: {
225
+ form,
226
+ ...useFormProps.formProps,
227
+ onValuesChange: formProps?.onValuesChange,
228
+ onKeyUp: formProps?.onKeyUp,
229
+ onFinish: formProps.onFinish,
230
+ },
231
+ drawerProps: {
232
+ width: "500px",
233
+ onClose: handleClose,
234
+ open,
235
+ forceRender: true,
236
+ },
237
+ saveButtonProps,
238
+ deleteButtonProps,
239
+ formLoading,
240
+ };
241
+ };
@@ -0,0 +1,168 @@
1
+ import React from "react";
2
+ import { FormInstance, FormProps, Form } from "antd";
3
+ import { useForm as useFormSF } from "sunflower-antd";
4
+ import { ButtonProps } from "antd";
5
+
6
+ import {
7
+ HttpError,
8
+ BaseRecord,
9
+ useForm as useFormCore,
10
+ UseFormReturnType as UseFormReturnTypeCore,
11
+ useWarnAboutChange,
12
+ UseFormProps as UseFormPropsCore,
13
+ CreateResponse,
14
+ UpdateResponse,
15
+ pickNotDeprecated,
16
+ } from "@refinedev/core";
17
+
18
+ export type UseFormProps<
19
+ TData extends BaseRecord = BaseRecord,
20
+ TError extends HttpError = HttpError,
21
+ TVariables = {},
22
+ > = UseFormPropsCore<TData, TError, TVariables> & {
23
+ submitOnEnter?: boolean;
24
+ /**
25
+ * Shows notification when unsaved changes exist
26
+ */
27
+ warnWhenUnsavedChanges?: boolean;
28
+ };
29
+
30
+ export type UseFormReturnType<
31
+ TData extends BaseRecord = BaseRecord,
32
+ TError extends HttpError = HttpError,
33
+ TVariables = {},
34
+ > = UseFormReturnTypeCore<TData, TError, TVariables> & {
35
+ form: FormInstance<TVariables>;
36
+ formProps: FormProps<TVariables>;
37
+ saveButtonProps: ButtonProps & {
38
+ onClick: () => void;
39
+ };
40
+ onFinish: (
41
+ values?: TVariables,
42
+ ) => Promise<CreateResponse<TData> | UpdateResponse<TData> | void>;
43
+ };
44
+
45
+ /**
46
+ * `useForm` is used to manage forms. It uses Ant Design {@link https://ant.design/components/form/ Form} data scope management under the hood and returns the required props for managing the form actions.
47
+ *
48
+ * @see {@link https://refine.dev/docs/api-references/hooks/form/useForm} for more details.
49
+ *
50
+ * @typeParam TData - Result data of the query extends {@link https://refine.dev/docs/api-references/interfaceReferences#baserecord `BaseRecord`}
51
+ * @typeParam TError - Custom error object that extends {@link https://refine.dev/docs/api-references/interfaceReferences#httperror `HttpError`}
52
+ * @typeParam TVariables - Values for params. default `{}`
53
+ *
54
+ *
55
+ */
56
+ export const useForm = <
57
+ TData extends BaseRecord = BaseRecord,
58
+ TError extends HttpError = HttpError,
59
+ TVariables = {},
60
+ >({
61
+ action,
62
+ resource,
63
+ onMutationSuccess: onMutationSuccessProp,
64
+ onMutationError,
65
+ submitOnEnter = false,
66
+ warnWhenUnsavedChanges: warnWhenUnsavedChangesProp,
67
+ redirect,
68
+ successNotification,
69
+ errorNotification,
70
+ meta,
71
+ metaData,
72
+ liveMode,
73
+ liveParams,
74
+ mutationMode,
75
+ dataProviderName,
76
+ onLiveEvent,
77
+ invalidates,
78
+ undoableTimeout,
79
+ queryOptions,
80
+ createMutationOptions,
81
+ updateMutationOptions,
82
+ id: idFromProps,
83
+ }: UseFormProps<TData, TError, TVariables> = {}): UseFormReturnType<
84
+ TData,
85
+ TError,
86
+ TVariables
87
+ > => {
88
+ const [formAnt] = Form.useForm();
89
+ const formSF = useFormSF<TData, TVariables>({
90
+ form: formAnt,
91
+ });
92
+ const { form } = formSF;
93
+
94
+ const useFormCoreResult = useFormCore<TData, TError, TVariables>({
95
+ onMutationSuccess: onMutationSuccessProp
96
+ ? onMutationSuccessProp
97
+ : undefined,
98
+ onMutationError,
99
+ redirect,
100
+ action,
101
+ resource,
102
+ successNotification,
103
+ errorNotification,
104
+ meta: pickNotDeprecated(meta, metaData),
105
+ metaData: pickNotDeprecated(meta, metaData),
106
+ liveMode,
107
+ liveParams,
108
+ mutationMode,
109
+ dataProviderName,
110
+ onLiveEvent,
111
+ invalidates,
112
+ undoableTimeout,
113
+ queryOptions,
114
+ createMutationOptions,
115
+ updateMutationOptions,
116
+ id: idFromProps,
117
+ });
118
+
119
+ const { formLoading, onFinish, queryResult, id } = useFormCoreResult;
120
+
121
+ const {
122
+ warnWhenUnsavedChanges: warnWhenUnsavedChangesRefine,
123
+ setWarnWhen,
124
+ } = useWarnAboutChange();
125
+ const warnWhenUnsavedChanges =
126
+ warnWhenUnsavedChangesProp ?? warnWhenUnsavedChangesRefine;
127
+
128
+ React.useEffect(() => {
129
+ form.resetFields();
130
+ }, [queryResult?.data?.data, id]);
131
+
132
+ const onKeyUp = (event: React.KeyboardEvent<HTMLFormElement>) => {
133
+ if (submitOnEnter && event.key === "Enter") {
134
+ form.submit();
135
+ }
136
+ };
137
+
138
+ const onValuesChange = (changeValues: object) => {
139
+ if (changeValues && warnWhenUnsavedChanges) {
140
+ setWarnWhen(true);
141
+ }
142
+ return changeValues;
143
+ };
144
+
145
+ const saveButtonProps = {
146
+ disabled: formLoading,
147
+ onClick: () => {
148
+ form.submit();
149
+ },
150
+ };
151
+
152
+ return {
153
+ form: formSF.form,
154
+ formProps: {
155
+ ...formSF.formProps,
156
+ onFinish: (values: TVariables) =>
157
+ onFinish(values).catch((error) => error),
158
+ onKeyUp,
159
+ onValuesChange,
160
+ initialValues: queryResult?.data?.data,
161
+ },
162
+ saveButtonProps,
163
+ ...useFormCoreResult,
164
+ onFinish: async (values?: TVariables) => {
165
+ return await onFinish(values ?? formSF.form.getFieldsValue(true));
166
+ },
167
+ };
168
+ };
@@ -0,0 +1,5 @@
1
+ export {
2
+ useModalForm,
3
+ UseModalFormProps,
4
+ UseModalFormReturnType,
5
+ } from "./useModalForm";
@@ -0,0 +1,286 @@
1
+ import { useCallback, useEffect } from "react";
2
+ import { FormInstance, FormProps, ModalProps } from "antd";
3
+ import {
4
+ useModalForm as useModalFormSF,
5
+ UseModalFormConfig as UseModalFormConfigSF,
6
+ } from "sunflower-antd";
7
+
8
+ import {
9
+ useMutationMode,
10
+ useTranslate,
11
+ useWarnAboutChange,
12
+ HttpError,
13
+ UseFormProps as UseFormPropsCore,
14
+ BaseRecord,
15
+ LiveModeProps,
16
+ BaseKey,
17
+ userFriendlyResourceName,
18
+ useResource,
19
+ FormWithSyncWithLocationParams,
20
+ useParsed,
21
+ useGo,
22
+ } from "@refinedev/core";
23
+ import { useForm, UseFormProps, UseFormReturnType } from "../useForm";
24
+ import React from "react";
25
+
26
+ export type useModalFormFromSFReturnType<TData, TVariables> = {
27
+ open: boolean;
28
+ form: FormInstance<TVariables>;
29
+ show: (id?: BaseKey) => void;
30
+ close: () => void;
31
+ modalProps: ModalProps;
32
+ formProps: FormProps<TVariables>;
33
+ formLoading: boolean;
34
+ defaultFormValuesLoading: boolean;
35
+ formValues: {};
36
+ initialValues: {};
37
+ formResult: undefined;
38
+ submit: (values?: TVariables) => Promise<TData>;
39
+ /** @deprecated Please use `open` instead. */
40
+ visible: boolean;
41
+ };
42
+
43
+ type useModalFormConfig = {
44
+ action: "show" | "edit" | "create" | "clone";
45
+ };
46
+
47
+ export type UseModalFormReturnType<
48
+ TData extends BaseRecord = BaseRecord,
49
+ TError extends HttpError = HttpError,
50
+ TVariables = {},
51
+ > = Omit<
52
+ UseFormReturnType<TData, TError, TVariables>,
53
+ "saveButtonProps" | "deleteButtonProps"
54
+ > &
55
+ useModalFormFromSFReturnType<TData, TVariables>;
56
+
57
+ export type UseModalFormProps<
58
+ TData extends BaseRecord = BaseRecord,
59
+ TError extends HttpError = HttpError,
60
+ TVariables = {},
61
+ > = UseFormPropsCore<TData, TError, TVariables> &
62
+ UseFormProps<TData, TError, TVariables> &
63
+ UseModalFormConfigSF &
64
+ useModalFormConfig &
65
+ LiveModeProps &
66
+ FormWithSyncWithLocationParams;
67
+ /**
68
+ * `useModalForm` hook allows you to manage a form within a modal. It returns Ant Design {@link https://ant.design/components/form/ Form} and {@link https://ant.design/components/modal/ Modal} components props.
69
+ *
70
+ * @see {@link https://refine.dev/docs/ui-frameworks/antd/hooks/form/useModalForm} for more details.
71
+ *
72
+ * @typeParam TData - Result data of the query extends {@link https://refine.dev/docs/api-references/interfaceReferences#baserecord `BaseRecord`}
73
+ * @typeParam TError - Custom error object that extends {@link https://refine.dev/docs/api-references/interfaceReferences#httperror `HttpError`}
74
+ * @typeParam TVariables - Values for params. default `{}`
75
+ *
76
+ *
77
+ */
78
+ export const useModalForm = <
79
+ TData extends BaseRecord = BaseRecord,
80
+ TError extends HttpError = HttpError,
81
+ TVariables = {},
82
+ >({
83
+ mutationMode: mutationModeProp,
84
+ syncWithLocation,
85
+ ...rest
86
+ }: UseModalFormProps<TData, TError, TVariables>): UseModalFormReturnType<
87
+ TData,
88
+ TError,
89
+ TVariables
90
+ > => {
91
+ const initiallySynced = React.useRef(false);
92
+
93
+ const useFormProps = useForm<TData, TError, TVariables>({
94
+ ...rest,
95
+ mutationMode: mutationModeProp,
96
+ });
97
+
98
+ const { form, formProps, id, setId, formLoading, mutationResult } =
99
+ useFormProps;
100
+
101
+ const { resource, action: actionFromParams } = useResource(rest.resource);
102
+
103
+ const parsed = useParsed();
104
+ const go = useGo();
105
+
106
+ const action = rest.action ?? actionFromParams ?? "";
107
+
108
+ const syncingId =
109
+ typeof syncWithLocation === "object" && syncWithLocation.syncId;
110
+
111
+ const syncWithLocationKey =
112
+ typeof syncWithLocation === "object" && "key" in syncWithLocation
113
+ ? syncWithLocation.key
114
+ : resource && action && syncWithLocation
115
+ ? `modal-${resource?.identifier ?? resource?.name}-${action}`
116
+ : undefined;
117
+
118
+ const translate = useTranslate();
119
+
120
+ const { warnWhen, setWarnWhen } = useWarnAboutChange();
121
+
122
+ const sunflowerUseModal = useModalFormSF<TData, TVariables>({
123
+ ...rest,
124
+ form: form,
125
+ });
126
+
127
+ const {
128
+ visible,
129
+ close,
130
+ show,
131
+ form: modalForm,
132
+ formProps: modalFormProps,
133
+ modalProps,
134
+ } = sunflowerUseModal;
135
+
136
+ React.useEffect(() => {
137
+ if (initiallySynced.current === false && syncWithLocationKey) {
138
+ const openStatus = parsed?.params?.[syncWithLocationKey]?.open;
139
+ if (typeof openStatus === "boolean") {
140
+ if (openStatus) {
141
+ show();
142
+ }
143
+ } else if (typeof openStatus === "string") {
144
+ if (openStatus === "true") {
145
+ show();
146
+ }
147
+ }
148
+
149
+ if (syncingId) {
150
+ const idFromParams = parsed?.params?.[syncWithLocationKey]?.id;
151
+ if (idFromParams) {
152
+ setId?.(idFromParams);
153
+ }
154
+ }
155
+
156
+ initiallySynced.current = true;
157
+ }
158
+ }, [syncWithLocationKey, parsed, syncingId, setId]);
159
+
160
+ React.useEffect(() => {
161
+ if (initiallySynced.current === true) {
162
+ if (visible && syncWithLocationKey) {
163
+ go({
164
+ query: {
165
+ [syncWithLocationKey]: {
166
+ ...parsed?.params?.[syncWithLocationKey],
167
+ open: true,
168
+ ...(syncingId && id && { id }),
169
+ },
170
+ },
171
+ options: { keepQuery: true },
172
+ type: "replace",
173
+ });
174
+ } else if (syncWithLocationKey && !visible) {
175
+ go({
176
+ query: {
177
+ [syncWithLocationKey]: undefined,
178
+ },
179
+ options: { keepQuery: true },
180
+ type: "replace",
181
+ });
182
+ }
183
+ }
184
+ }, [id, visible, show, syncWithLocationKey, syncingId]);
185
+
186
+ const { mutationMode: mutationModeContext } = useMutationMode();
187
+ const mutationMode = mutationModeProp ?? mutationModeContext;
188
+
189
+ const {
190
+ isLoading: isLoadingMutation,
191
+ isSuccess: isSuccessMutation,
192
+ reset: resetMutation,
193
+ } = mutationResult ?? {};
194
+
195
+ useEffect(() => {
196
+ if (visible && mutationMode === "pessimistic") {
197
+ if (isSuccessMutation && !isLoadingMutation) {
198
+ close();
199
+ resetMutation?.();
200
+ // Prevents resetting form values before closing modal in UI
201
+ setTimeout(() => {
202
+ form.resetFields();
203
+ });
204
+ }
205
+ }
206
+ }, [isSuccessMutation, isLoadingMutation]);
207
+
208
+ const saveButtonPropsSF = {
209
+ disabled: formLoading,
210
+ onClick: () => {
211
+ modalForm.submit();
212
+
213
+ if (!(mutationMode === "pessimistic")) {
214
+ close();
215
+ // Prevents resetting form values before closing modal in UI
216
+ setTimeout(() => {
217
+ form.resetFields();
218
+ });
219
+ }
220
+ },
221
+ loading: formLoading,
222
+ };
223
+
224
+ const handleClose = useCallback(() => {
225
+ if (warnWhen) {
226
+ const warnWhenConfirm = window.confirm(
227
+ translate(
228
+ "warnWhenUnsavedChanges",
229
+ "Are you sure you want to leave? You have unsaved changes.",
230
+ ),
231
+ );
232
+
233
+ if (warnWhenConfirm) {
234
+ setWarnWhen(false);
235
+ } else {
236
+ return;
237
+ }
238
+ }
239
+
240
+ setId?.(undefined);
241
+ sunflowerUseModal.close();
242
+ }, [warnWhen]);
243
+
244
+ const handleShow = useCallback((id?: BaseKey) => {
245
+ setId?.(id);
246
+
247
+ sunflowerUseModal.show();
248
+ }, []);
249
+
250
+ return {
251
+ ...useFormProps,
252
+ ...sunflowerUseModal,
253
+ show: handleShow,
254
+ close: handleClose,
255
+ open: visible,
256
+ formProps: {
257
+ ...modalFormProps,
258
+ ...useFormProps.formProps,
259
+ onValuesChange: formProps?.onValuesChange,
260
+ onKeyUp: formProps?.onKeyUp,
261
+ onFinish: formProps.onFinish,
262
+ },
263
+ modalProps: {
264
+ ...modalProps,
265
+ width: "1000px",
266
+ okButtonProps: saveButtonPropsSF,
267
+ title: translate(
268
+ `${resource?.name}.titles.${rest.action}`,
269
+ `${userFriendlyResourceName(
270
+ `${rest.action} ${
271
+ resource?.meta?.label ??
272
+ resource?.options?.label ??
273
+ resource?.label ??
274
+ resource?.name
275
+ }`,
276
+ "singular",
277
+ )}`,
278
+ ),
279
+ okText: translate("buttons.save", "Save"),
280
+ cancelText: translate("buttons.cancel", "Cancel"),
281
+ onCancel: handleClose,
282
+ forceRender: true,
283
+ },
284
+ formLoading,
285
+ };
286
+ };
@@ -0,0 +1,5 @@
1
+ export {
2
+ useStepsForm,
3
+ UseStepsFormProps,
4
+ UseStepsFormReturnType,
5
+ } from "./useStepsForm";