nucleus-core-ts 0.8.7 → 0.8.9

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 (214) hide show
  1. package/dist/client.js +1 -1
  2. package/dist/fe/components/AbstractAnimatedBackground/index.js +437 -0
  3. package/dist/fe/components/AuthorizationPage/components/AuthorizationPage.js +841 -0
  4. package/dist/fe/components/AuthorizationPage/components/ClaimList.js +100 -0
  5. package/dist/fe/components/AuthorizationPage/components/RoleClaimEditor.js +232 -0
  6. package/dist/fe/components/AuthorizationPage/components/RoleList.js +115 -0
  7. package/dist/fe/components/AuthorizationPage/index.js +6 -0
  8. package/dist/fe/components/AuthorizationPage/store/index.js +117 -0
  9. package/dist/fe/components/AuthorizationPage/theme/index.js +137 -0
  10. package/dist/fe/components/AuthorizationPage/types/index.js +1 -0
  11. package/dist/fe/components/Button/components/Button.js +158 -0
  12. package/dist/fe/components/Button/components/ButtonSpinner.js +52 -0
  13. package/dist/fe/components/Button/index.js +3 -0
  14. package/dist/fe/components/Button/theme/index.js +186 -0
  15. package/dist/fe/components/Button/types/index.js +1 -0
  16. package/dist/fe/components/Button/utils/cn.js +5 -0
  17. package/dist/fe/components/Captcha/components/Captcha.js +311 -0
  18. package/dist/fe/components/Captcha/index.js +2 -0
  19. package/dist/fe/components/Captcha/theme.js +52 -0
  20. package/dist/fe/components/Captcha/types.js +1 -0
  21. package/dist/fe/components/ChangePasswordPage/components/ChangePasswordForm.js +242 -0
  22. package/dist/fe/components/ChangePasswordPage/components/ChangePasswordHeader.js +39 -0
  23. package/dist/fe/components/ChangePasswordPage/components/ChangePasswordPage.js +60 -0
  24. package/dist/fe/components/ChangePasswordPage/index.js +5 -0
  25. package/dist/fe/components/ChangePasswordPage/store/index.js +44 -0
  26. package/dist/fe/components/ChangePasswordPage/theme/index.js +87 -0
  27. package/dist/fe/components/ChangePasswordPage/types/index.js +1 -0
  28. package/dist/fe/components/Checkbox/components/Checkbox.js +115 -0
  29. package/dist/fe/components/Checkbox/components/CheckboxIcon.js +119 -0
  30. package/dist/fe/components/Checkbox/components/SwitchTrack.js +178 -0
  31. package/dist/fe/components/Checkbox/index.js +4 -0
  32. package/dist/fe/components/Checkbox/theme/index.js +221 -0
  33. package/dist/fe/components/Checkbox/types/index.js +1 -0
  34. package/dist/fe/components/Checkbox/utils/cn.js +5 -0
  35. package/dist/fe/components/DataTable/DataTable.js +225 -0
  36. package/dist/fe/components/DataTable/components/ActionCell.js +26 -0
  37. package/dist/fe/components/DataTable/components/DataCell.js +76 -0
  38. package/dist/fe/components/DataTable/components/EditableCell.js +221 -0
  39. package/dist/fe/components/DataTable/components/EmptyState.js +29 -0
  40. package/dist/fe/components/DataTable/components/HeaderCell.js +64 -0
  41. package/dist/fe/components/DataTable/components/InfiniteScrollTrigger.js +66 -0
  42. package/dist/fe/components/DataTable/components/LoadingSpinner.js +19 -0
  43. package/dist/fe/components/DataTable/components/ResizeHandle.js +41 -0
  44. package/dist/fe/components/DataTable/components/SelectionCell.js +105 -0
  45. package/dist/fe/components/DataTable/components/SkeletonRow.js +56 -0
  46. package/dist/fe/components/DataTable/components/SkeletonTable.js +83 -0
  47. package/dist/fe/components/DataTable/components/SortIcon.js +39 -0
  48. package/dist/fe/components/DataTable/components/TableHeader.js +49 -0
  49. package/dist/fe/components/DataTable/components/TableRow.js +118 -0
  50. package/dist/fe/components/DataTable/components/index.js +14 -0
  51. package/dist/fe/components/DataTable/hooks/index.js +2 -0
  52. package/dist/fe/components/DataTable/hooks/useAutoFitColumn.js +23 -0
  53. package/dist/fe/components/DataTable/hooks/useResizeColumn.js +122 -0
  54. package/dist/fe/components/DataTable/index.js +3 -0
  55. package/dist/fe/components/DataTable/store/index.js +97 -0
  56. package/dist/fe/components/DataTable/theme/index.js +144 -0
  57. package/dist/fe/components/DataTable/types/index.js +1 -0
  58. package/dist/fe/components/DataTable/utils/cn.js +5 -0
  59. package/dist/fe/components/DatePicker/components/CalendarGrid.js +95 -0
  60. package/dist/fe/components/DatePicker/components/CalendarHeader.js +152 -0
  61. package/dist/fe/components/DatePicker/components/DatePicker.js +381 -0
  62. package/dist/fe/components/DatePicker/components/MonthYearSelector.js +93 -0
  63. package/dist/fe/components/DatePicker/index.js +7 -0
  64. package/dist/fe/components/DatePicker/locales/index.js +1113 -0
  65. package/dist/fe/components/DatePicker/theme/index.js +315 -0
  66. package/dist/fe/components/DatePicker/types/index.js +1 -0
  67. package/dist/fe/components/DatePicker/utils/cn.js +5 -0
  68. package/dist/fe/components/DatePicker/utils/date.js +132 -0
  69. package/dist/fe/components/DevicesPage/components/DeviceCard.js +251 -0
  70. package/dist/fe/components/DevicesPage/components/DevicesHeader.js +42 -0
  71. package/dist/fe/components/DevicesPage/components/DevicesPage.js +450 -0
  72. package/dist/fe/components/DevicesPage/index.js +5 -0
  73. package/dist/fe/components/DevicesPage/store/index.js +55 -0
  74. package/dist/fe/components/DevicesPage/theme/index.js +131 -0
  75. package/dist/fe/components/DevicesPage/types/index.js +1 -0
  76. package/dist/fe/components/ForgotPasswordPage/components/ForgotPasswordForm.js +214 -0
  77. package/dist/fe/components/ForgotPasswordPage/components/ForgotPasswordHeader.js +42 -0
  78. package/dist/fe/components/ForgotPasswordPage/components/ForgotPasswordPage.js +59 -0
  79. package/dist/fe/components/ForgotPasswordPage/index.js +5 -0
  80. package/dist/fe/components/ForgotPasswordPage/store/index.js +28 -0
  81. package/dist/fe/components/ForgotPasswordPage/theme/index.js +87 -0
  82. package/dist/fe/components/ForgotPasswordPage/types/index.js +1 -0
  83. package/dist/fe/components/FormBuilder/components/FormBuilder.js +156 -0
  84. package/dist/fe/components/FormBuilder/components/FormField.js +218 -0
  85. package/dist/fe/components/FormBuilder/hooks/useFormBuilder.js +152 -0
  86. package/dist/fe/components/FormBuilder/index.js +4 -0
  87. package/dist/fe/components/FormBuilder/theme/index.js +134 -0
  88. package/dist/fe/components/FormBuilder/types/index.js +1 -0
  89. package/dist/fe/components/FormBuilder/utils/cn.js +5 -0
  90. package/dist/fe/components/FormBuilder/utils/fieldMapping.js +216 -0
  91. package/dist/fe/components/FormBuilder/utils/validation.js +78 -0
  92. package/dist/fe/components/LoginPage/components/LoginForm.js +214 -0
  93. package/dist/fe/components/LoginPage/components/LoginHeader.js +24 -0
  94. package/dist/fe/components/LoginPage/components/LoginPage.js +138 -0
  95. package/dist/fe/components/LoginPage/index.js +5 -0
  96. package/dist/fe/components/LoginPage/store/index.js +59 -0
  97. package/dist/fe/components/LoginPage/theme/index.js +98 -0
  98. package/dist/fe/components/LoginPage/types/index.js +1 -0
  99. package/dist/fe/components/MagicLinkVerifyPage/components/MagicLinkVerifyPage.js +200 -0
  100. package/dist/fe/components/MagicLinkVerifyPage/index.js +3 -0
  101. package/dist/fe/components/MagicLinkVerifyPage/store.js +20 -0
  102. package/dist/fe/components/MagicLinkVerifyPage/theme.js +36 -0
  103. package/dist/fe/components/MagicLinkVerifyPage/types.js +1 -0
  104. package/dist/fe/components/NucleusEntityShowcase.js +1409 -0
  105. package/dist/fe/components/NucleusTextInput/components/FloatingLabel.js +56 -0
  106. package/dist/fe/components/NucleusTextInput/components/InputIcons.js +258 -0
  107. package/dist/fe/components/NucleusTextInput/components/NucleusTextInput.js +321 -0
  108. package/dist/fe/components/NucleusTextInput/components/PasswordStrengthIndicator.js +104 -0
  109. package/dist/fe/components/NucleusTextInput/components/TypewriterText.js +56 -0
  110. package/dist/fe/components/NucleusTextInput/index.js +7 -0
  111. package/dist/fe/components/NucleusTextInput/theme/index.js +121 -0
  112. package/dist/fe/components/NucleusTextInput/types/index.js +1 -0
  113. package/dist/fe/components/NucleusTextInput/utils/cn.js +5 -0
  114. package/dist/fe/components/NucleusTextInput/utils/format.js +62 -0
  115. package/dist/fe/components/NucleusTextInput/utils/validation.js +191 -0
  116. package/dist/fe/components/ProfilePage/components/AddressCard.js +196 -0
  117. package/dist/fe/components/ProfilePage/components/PhoneCard.js +206 -0
  118. package/dist/fe/components/ProfilePage/components/ProfileHeader.js +150 -0
  119. package/dist/fe/components/ProfilePage/components/ProfilePage.js +1336 -0
  120. package/dist/fe/components/ProfilePage/index.js +6 -0
  121. package/dist/fe/components/ProfilePage/store/index.js +115 -0
  122. package/dist/fe/components/ProfilePage/theme/index.js +168 -0
  123. package/dist/fe/components/ProfilePage/types/index.js +1 -0
  124. package/dist/fe/components/RangePicker/components/RangePicker.js +338 -0
  125. package/dist/fe/components/RangePicker/components/RangeThumb.js +68 -0
  126. package/dist/fe/components/RangePicker/components/RangeTooltip.js +45 -0
  127. package/dist/fe/components/RangePicker/components/RangeTrack.js +32 -0
  128. package/dist/fe/components/RangePicker/index.js +5 -0
  129. package/dist/fe/components/RangePicker/theme/index.js +88 -0
  130. package/dist/fe/components/RangePicker/types/index.js +1 -0
  131. package/dist/fe/components/RangePicker/utils/cn.js +3 -0
  132. package/dist/fe/components/RegisterPage/components/PasswordStrengthIndicator.js +107 -0
  133. package/dist/fe/components/RegisterPage/components/RegisterForm.js +322 -0
  134. package/dist/fe/components/RegisterPage/components/RegisterHeader.js +23 -0
  135. package/dist/fe/components/RegisterPage/components/RegisterPage.js +85 -0
  136. package/dist/fe/components/RegisterPage/index.js +6 -0
  137. package/dist/fe/components/RegisterPage/store/index.js +106 -0
  138. package/dist/fe/components/RegisterPage/theme/index.js +128 -0
  139. package/dist/fe/components/RegisterPage/types/index.js +1 -0
  140. package/dist/fe/components/ResetPasswordPage/components/ResetPasswordForm.js +347 -0
  141. package/dist/fe/components/ResetPasswordPage/components/ResetPasswordHeader.js +42 -0
  142. package/dist/fe/components/ResetPasswordPage/components/ResetPasswordPage.js +61 -0
  143. package/dist/fe/components/ResetPasswordPage/index.js +5 -0
  144. package/dist/fe/components/ResetPasswordPage/store/index.js +36 -0
  145. package/dist/fe/components/ResetPasswordPage/theme/index.js +99 -0
  146. package/dist/fe/components/ResetPasswordPage/types/index.js +1 -0
  147. package/dist/fe/components/SearchBox/components/SearchBox.js +271 -0
  148. package/dist/fe/components/SearchBox/components/SearchBoxDropdown.js +87 -0
  149. package/dist/fe/components/SearchBox/index.js +5 -0
  150. package/dist/fe/components/SearchBox/theme/index.js +184 -0
  151. package/dist/fe/components/SearchBox/types/index.js +1 -0
  152. package/dist/fe/components/SearchBox/utils/cn.js +5 -0
  153. package/dist/fe/components/SearchBox/utils/debounce.js +22 -0
  154. package/dist/fe/components/SearchBox/utils/sanitize.js +48 -0
  155. package/dist/fe/components/SelectBox/components/SelectBox.js +364 -0
  156. package/dist/fe/components/SelectBox/components/SelectDropdown.js +92 -0
  157. package/dist/fe/components/SelectBox/components/SelectOptionItem.js +43 -0
  158. package/dist/fe/components/SelectBox/components/SelectTrigger.js +22 -0
  159. package/dist/fe/components/SelectBox/index.js +5 -0
  160. package/dist/fe/components/SelectBox/theme/index.js +98 -0
  161. package/dist/fe/components/SelectBox/types/index.js +1 -0
  162. package/dist/fe/components/SelectBox/utils/cn.js +3 -0
  163. package/dist/fe/components/SetPasswordPage/components/PasswordStrengthIndicator.js +107 -0
  164. package/dist/fe/components/SetPasswordPage/components/SetPasswordForm.js +142 -0
  165. package/dist/fe/components/SetPasswordPage/components/SetPasswordHeader.js +23 -0
  166. package/dist/fe/components/SetPasswordPage/components/SetPasswordPage.js +263 -0
  167. package/dist/fe/components/SetPasswordPage/index.js +7 -0
  168. package/dist/fe/components/SetPasswordPage/store/index.js +79 -0
  169. package/dist/fe/components/SetPasswordPage/theme/index.js +98 -0
  170. package/dist/fe/components/SetPasswordPage/types/index.js +12 -0
  171. package/dist/fe/components/UsersPage/components/InviteUserModal.js +262 -0
  172. package/dist/fe/components/UsersPage/components/Pagination.js +147 -0
  173. package/dist/fe/components/UsersPage/components/RoleAssignmentModal.js +186 -0
  174. package/dist/fe/components/UsersPage/components/StatsCards.js +124 -0
  175. package/dist/fe/components/UsersPage/components/UserDetailDrawer.js +444 -0
  176. package/dist/fe/components/UsersPage/components/UserFilters.js +142 -0
  177. package/dist/fe/components/UsersPage/components/UserListItem.js +125 -0
  178. package/dist/fe/components/UsersPage/components/UserListSkeleton.js +40 -0
  179. package/dist/fe/components/UsersPage/components/UsersPage.js +556 -0
  180. package/dist/fe/components/UsersPage/index.js +10 -0
  181. package/dist/fe/components/UsersPage/store/index.js +151 -0
  182. package/dist/fe/components/UsersPage/theme/index.js +231 -0
  183. package/dist/fe/components/UsersPage/types/index.js +1 -0
  184. package/dist/fe/components/VerifyEmailPage/components/VerifyEmailPage.js +290 -0
  185. package/dist/fe/components/VerifyEmailPage/index.js +3 -0
  186. package/dist/fe/components/VerifyEmailPage/store/index.js +45 -0
  187. package/dist/fe/components/VerifyEmailPage/theme/index.js +52 -0
  188. package/dist/fe/components/VerifyEmailPage/types/index.js +1 -0
  189. package/dist/fe/hooks/useNucleusEntity.js +247 -0
  190. package/dist/fe/index.js +28 -157
  191. package/dist/fe/types/index.js +1 -0
  192. package/dist/fe/utils/cn.js +5 -0
  193. package/dist/fe/utils/columnUtils.js +189 -0
  194. package/dist/fe/utils/endpointKeys.js +44 -0
  195. package/dist/index.js +1 -1
  196. package/dist/nucleus.config.d.ts +2 -0
  197. package/dist/src/Client/ApiCaller/client.js +1 -0
  198. package/dist/src/Client/ApiCaller/examples/usage.example.js +1 -0
  199. package/dist/src/Client/ApiCaller/generator.js +1 -0
  200. package/dist/src/Client/ApiCaller/index.js +1 -0
  201. package/dist/src/Client/ApiCaller/server.js +1 -0
  202. package/dist/src/Client/ApiCaller/system-tables.js +1 -0
  203. package/dist/src/Client/ApiCaller/types.js +1 -0
  204. package/dist/src/Client/Proxy/httpProxy.js +1 -0
  205. package/dist/src/Client/Proxy/index.js +1 -1
  206. package/dist/src/Client/Proxy/server.js +1 -0
  207. package/dist/src/Client/Proxy/types.js +1 -0
  208. package/dist/src/Client/Proxy/utils.js +1 -0
  209. package/dist/src/Client/Proxy/wsProxy.js +1 -0
  210. package/dist/src/Client/ServerFetch/index.js +1 -0
  211. package/dist/src/Client/ServerFetch/types.js +1 -0
  212. package/dist/src/Client/index.js +1 -0
  213. package/package.json +1 -1
  214. package/scripts/build.ts +41 -16
@@ -0,0 +1,218 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useGSAP } from "@gsap/react";
4
+ import gsap from "gsap";
5
+ import { useRef } from "react";
6
+ import { Checkbox } from "../../Checkbox";
7
+ import { DatePicker } from "../../DatePicker";
8
+ import { NucleusTextInput } from "../../NucleusTextInput";
9
+ import { SelectBox } from "../../SelectBox";
10
+ import { formBuilderTheme } from "../theme";
11
+ import { cn } from "../utils/cn";
12
+ import { formatLabel, getFieldMapping } from "../utils/fieldMapping";
13
+ gsap.registerPlugin(useGSAP);
14
+ export function FormField({ column, config, value, onChange, error, size = "md", locale = "en-US", disabled = false, readOnly = false }) {
15
+ const theme = formBuilderTheme.field;
16
+ const containerRef = useRef(null);
17
+ const errorRef = useRef(null);
18
+ const fieldMapping = getFieldMapping(column);
19
+ const label = config.label ?? formatLabel(column.name);
20
+ const placeholder = config.placeholder ?? `Enter ${label.toLowerCase()}`;
21
+ const isRequired = config.required ?? column.notNull ?? false;
22
+ const isDisabled = disabled || config.disabled;
23
+ const isReadOnly = readOnly || config.readOnly;
24
+ useGSAP(()=>{
25
+ if (error && errorRef.current) {
26
+ gsap.fromTo(errorRef.current, {
27
+ opacity: 0,
28
+ y: -5
29
+ }, {
30
+ opacity: 1,
31
+ y: 0,
32
+ duration: formBuilderTheme.animation.field.error.duration,
33
+ ease: formBuilderTheme.animation.field.error.ease
34
+ });
35
+ }
36
+ }, [
37
+ error
38
+ ]);
39
+ const renderInput = ()=>{
40
+ switch(fieldMapping.inputType){
41
+ case "checkbox":
42
+ return /*#__PURE__*/ _jsx(Checkbox, {
43
+ checked: Boolean(value),
44
+ onChange: (checked)=>onChange(checked),
45
+ label: label,
46
+ size: size,
47
+ disabled: isDisabled,
48
+ errorMessage: error,
49
+ helperText: config.helperText
50
+ });
51
+ case "select":
52
+ {
53
+ const options = getSelectOptions(column, config.options);
54
+ return /*#__PURE__*/ _jsx(SelectBox, {
55
+ options: options,
56
+ value: value,
57
+ onChange: (val)=>onChange(val),
58
+ placeholder: placeholder,
59
+ label: label,
60
+ size: size,
61
+ disabled: isDisabled,
62
+ readOnly: isReadOnly,
63
+ required: isRequired,
64
+ error: error,
65
+ helperText: config.helperText,
66
+ clearable: !isRequired
67
+ });
68
+ }
69
+ case "date":
70
+ return /*#__PURE__*/ _jsx(DatePicker, {
71
+ mode: "single",
72
+ value: value,
73
+ onChange: (val)=>onChange(val),
74
+ placeholder: placeholder,
75
+ label: label,
76
+ disabled: isDisabled,
77
+ locale: locale,
78
+ errorMessage: error,
79
+ helperText: config.helperText,
80
+ required: isRequired
81
+ });
82
+ case "datetime":
83
+ return /*#__PURE__*/ _jsx(DatePicker, {
84
+ mode: "single",
85
+ value: value,
86
+ onChange: (val)=>onChange(val),
87
+ placeholder: placeholder,
88
+ label: label,
89
+ disabled: isDisabled,
90
+ locale: locale,
91
+ errorMessage: error,
92
+ helperText: config.helperText,
93
+ required: isRequired
94
+ });
95
+ case "number":
96
+ return /*#__PURE__*/ _jsx(NucleusTextInput, {
97
+ type: "number",
98
+ value: value !== null && value !== undefined ? String(value) : "",
99
+ onChange: (val)=>{
100
+ const num = val === "" ? null : Number(val);
101
+ onChange(num);
102
+ },
103
+ placeholder: placeholder,
104
+ label: label,
105
+ size: size,
106
+ disabled: isDisabled,
107
+ readOnly: isReadOnly,
108
+ errorMessage: error,
109
+ helperText: config.helperText
110
+ });
111
+ case "textarea":
112
+ return /*#__PURE__*/ _jsx(NucleusTextInput, {
113
+ type: "text",
114
+ value: value ?? "",
115
+ onChange: (val)=>onChange(val),
116
+ placeholder: placeholder,
117
+ label: label,
118
+ size: size,
119
+ disabled: isDisabled,
120
+ readOnly: isReadOnly,
121
+ errorMessage: error,
122
+ helperText: config.helperText,
123
+ enableValidation: true,
124
+ validationConfig: {
125
+ minLength: column.validation?.minLength,
126
+ maxLength: column.validation?.maxLength
127
+ }
128
+ });
129
+ case "json":
130
+ return /*#__PURE__*/ _jsx(NucleusTextInput, {
131
+ type: "text",
132
+ value: typeof value === "object" ? JSON.stringify(value, null, 2) : "",
133
+ onChange: (val)=>{
134
+ try {
135
+ const parsed = JSON.parse(val);
136
+ onChange(parsed);
137
+ } catch {
138
+ onChange(val);
139
+ }
140
+ },
141
+ placeholder: placeholder,
142
+ label: label,
143
+ size: size,
144
+ disabled: isDisabled,
145
+ readOnly: isReadOnly,
146
+ errorMessage: error,
147
+ helperText: config.helperText
148
+ });
149
+ case "hidden":
150
+ return /*#__PURE__*/ _jsx("input", {
151
+ type: "hidden",
152
+ value: String(value ?? "")
153
+ });
154
+ default:
155
+ {
156
+ const inputType = getTextInputType(fieldMapping.inputType, column);
157
+ return /*#__PURE__*/ _jsx(NucleusTextInput, {
158
+ type: inputType,
159
+ value: value ?? "",
160
+ onChange: (val)=>onChange(val),
161
+ placeholder: placeholder,
162
+ label: label,
163
+ size: size,
164
+ disabled: isDisabled,
165
+ readOnly: isReadOnly,
166
+ errorMessage: error,
167
+ helperText: config.helperText,
168
+ enableValidation: true,
169
+ validationConfig: {
170
+ minLength: column.validation?.minLength,
171
+ maxLength: column.validation?.maxLength,
172
+ pattern: column.validation?.pattern ? new RegExp(column.validation.pattern) : undefined
173
+ }
174
+ });
175
+ }
176
+ }
177
+ };
178
+ if (config.hidden || fieldMapping.inputType === "hidden") {
179
+ return renderInput();
180
+ }
181
+ if (fieldMapping.inputType === "checkbox") {
182
+ return /*#__PURE__*/ _jsx("div", {
183
+ ref: containerRef,
184
+ className: cn(theme.container.base, config.span && theme.container.span[config.span]),
185
+ children: renderInput()
186
+ });
187
+ }
188
+ return /*#__PURE__*/ _jsx("div", {
189
+ ref: containerRef,
190
+ className: cn(theme.container.base, config.span && theme.container.span[config.span]),
191
+ children: renderInput()
192
+ });
193
+ }
194
+ function getSelectOptions(column, customOptions) {
195
+ if (customOptions) {
196
+ return customOptions;
197
+ }
198
+ if (column.enumValues) {
199
+ return column.enumValues.map((val)=>({
200
+ value: val,
201
+ label: formatLabel(val)
202
+ }));
203
+ }
204
+ if (column.enum) {
205
+ return column.enum.values.map((val)=>({
206
+ value: val,
207
+ label: formatLabel(val)
208
+ }));
209
+ }
210
+ return [];
211
+ }
212
+ function getTextInputType(_inputType, column) {
213
+ if (column.validation?.format === "email") return "email";
214
+ if (column.validation?.format === "url" || column.validation?.format === "uri") return "url";
215
+ if (column.name.toLowerCase().includes("password")) return "password";
216
+ if (column.name.toLowerCase().includes("phone")) return "tel";
217
+ return "text";
218
+ }
@@ -0,0 +1,152 @@
1
+ "use client";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { getDefaultValue, shouldExcludeField } from "../utils/fieldMapping";
4
+ import { validateField } from "../utils/validation";
5
+ export function useFormBuilder({ columns, initialValues, fieldConfigs, onSubmit, validate: customValidate }) {
6
+ const initialValuesRef = useRef(initialValues);
7
+ const getInitialState = ()=>{
8
+ const values = {};
9
+ for (const column of columns){
10
+ if (shouldExcludeField(column)) continue;
11
+ const fieldName = column.name;
12
+ const config = fieldConfigs?.[fieldName];
13
+ if (initialValuesRef.current?.[fieldName] !== undefined) {
14
+ values[fieldName] = initialValuesRef.current[fieldName];
15
+ } else if (config?.defaultValue !== undefined) {
16
+ values[fieldName] = config.defaultValue;
17
+ } else {
18
+ values[fieldName] = getDefaultValue(column);
19
+ }
20
+ }
21
+ return {
22
+ values,
23
+ errors: {},
24
+ touched: {},
25
+ isSubmitting: false,
26
+ isDirty: false
27
+ };
28
+ };
29
+ const [state, setState] = useState(getInitialState);
30
+ useEffect(()=>{
31
+ if (initialValues !== initialValuesRef.current) {
32
+ initialValuesRef.current = initialValues;
33
+ setState(getInitialState());
34
+ }
35
+ }, [
36
+ initialValues
37
+ ]);
38
+ const setValue = (name, value)=>{
39
+ setState((prev)=>({
40
+ ...prev,
41
+ values: {
42
+ ...prev.values,
43
+ [name]: value
44
+ },
45
+ isDirty: true
46
+ }));
47
+ };
48
+ const setValues = (values)=>{
49
+ setState((prev)=>({
50
+ ...prev,
51
+ values: {
52
+ ...prev.values,
53
+ ...values
54
+ },
55
+ isDirty: true
56
+ }));
57
+ };
58
+ const setError = (name, error)=>{
59
+ setState((prev)=>({
60
+ ...prev,
61
+ errors: {
62
+ ...prev.errors,
63
+ [name]: error
64
+ }
65
+ }));
66
+ };
67
+ const setErrors = (errors)=>{
68
+ setState((prev)=>({
69
+ ...prev,
70
+ errors: {
71
+ ...prev.errors,
72
+ ...errors
73
+ }
74
+ }));
75
+ };
76
+ const setTouched = (name, touched)=>{
77
+ setState((prev)=>({
78
+ ...prev,
79
+ touched: {
80
+ ...prev.touched,
81
+ [name]: touched
82
+ }
83
+ }));
84
+ };
85
+ const reset = ()=>{
86
+ setState(getInitialState());
87
+ };
88
+ const validateForm = ()=>{
89
+ const errors = {};
90
+ for (const column of columns){
91
+ if (shouldExcludeField(column)) continue;
92
+ const fieldName = column.name;
93
+ const config = fieldConfigs?.[fieldName];
94
+ const value = state.values[fieldName];
95
+ const isRequired = config?.required ?? column.notNull ?? false;
96
+ const error = validateField(column, value, isRequired);
97
+ if (error) {
98
+ errors[fieldName] = error;
99
+ }
100
+ }
101
+ if (customValidate) {
102
+ const customErrors = customValidate(state.values);
103
+ Object.assign(errors, customErrors);
104
+ }
105
+ setState((prev)=>({
106
+ ...prev,
107
+ errors
108
+ }));
109
+ return Object.keys(errors).length === 0;
110
+ };
111
+ const submit = async ()=>{
112
+ const isValid = validateForm();
113
+ if (!isValid) return;
114
+ setState((prev)=>({
115
+ ...prev,
116
+ isSubmitting: true
117
+ }));
118
+ try {
119
+ await onSubmit(state.values);
120
+ setState((prev)=>({
121
+ ...prev,
122
+ isSubmitting: false,
123
+ isDirty: false
124
+ }));
125
+ } catch (error) {
126
+ setState((prev)=>({
127
+ ...prev,
128
+ isSubmitting: false
129
+ }));
130
+ throw error;
131
+ }
132
+ };
133
+ const getFieldProps = (name)=>{
134
+ return {
135
+ value: state.values[name],
136
+ onChange: (value)=>setValue(name, value),
137
+ error: state.errors[name]
138
+ };
139
+ };
140
+ return {
141
+ state,
142
+ setValue,
143
+ setValues,
144
+ setError,
145
+ setErrors,
146
+ setTouched,
147
+ reset,
148
+ submit,
149
+ validate: validateForm,
150
+ getFieldProps
151
+ };
152
+ }
@@ -0,0 +1,4 @@
1
+ export { FormBuilder } from "./components/FormBuilder";
2
+ export { FormField } from "./components/FormField";
3
+ export { useFormBuilder } from "./hooks/useFormBuilder";
4
+ export { formBuilderTheme } from "./theme";
@@ -0,0 +1,134 @@
1
+ export const formBuilderTheme = {
2
+ container: {
3
+ base: "w-full"
4
+ },
5
+ form: {
6
+ base: "w-full",
7
+ layout: {
8
+ vertical: "flex flex-col",
9
+ horizontal: "flex flex-row flex-wrap",
10
+ inline: "flex flex-row flex-wrap items-end"
11
+ }
12
+ },
13
+ fields: {
14
+ base: "grid w-full",
15
+ columns: {
16
+ 1: "grid-cols-1",
17
+ 2: "grid-cols-1 sm:grid-cols-2",
18
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
19
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
20
+ 6: "grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6",
21
+ 12: "grid-cols-1 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-12"
22
+ },
23
+ gap: {
24
+ sm: "gap-3",
25
+ md: "gap-4",
26
+ lg: "gap-6"
27
+ }
28
+ },
29
+ field: {
30
+ container: {
31
+ base: "flex flex-col",
32
+ span: {
33
+ 1: "col-span-1",
34
+ 2: "col-span-1 sm:col-span-2",
35
+ 3: "col-span-1 sm:col-span-2 lg:col-span-3",
36
+ 4: "col-span-1 sm:col-span-2 lg:col-span-4",
37
+ 6: "col-span-1 sm:col-span-2 md:col-span-3 lg:col-span-6",
38
+ 12: "col-span-full"
39
+ }
40
+ },
41
+ label: {
42
+ base: "mb-1.5 text-sm font-medium",
43
+ color: {
44
+ light: "text-zinc-700",
45
+ dark: "dark:text-zinc-300"
46
+ },
47
+ required: "after:content-['*'] after:ml-0.5 after:text-red-500",
48
+ disabled: "opacity-50 cursor-not-allowed"
49
+ },
50
+ error: {
51
+ base: "mt-1 text-xs",
52
+ color: {
53
+ light: "text-red-500",
54
+ dark: "dark:text-red-400"
55
+ }
56
+ },
57
+ helper: {
58
+ base: "mt-1 text-xs",
59
+ color: {
60
+ light: "text-zinc-500",
61
+ dark: "dark:text-zinc-400"
62
+ }
63
+ }
64
+ },
65
+ actions: {
66
+ base: "flex items-center mt-6",
67
+ gap: {
68
+ sm: "gap-2",
69
+ md: "gap-3",
70
+ lg: "gap-4"
71
+ },
72
+ alignment: {
73
+ left: "justify-start",
74
+ center: "justify-center",
75
+ right: "justify-end",
76
+ between: "justify-between"
77
+ }
78
+ },
79
+ header: {
80
+ base: "mb-6",
81
+ title: {
82
+ base: "text-xl font-semibold",
83
+ color: {
84
+ light: "text-zinc-900",
85
+ dark: "dark:text-white"
86
+ }
87
+ },
88
+ description: {
89
+ base: "mt-1 text-sm",
90
+ color: {
91
+ light: "text-zinc-500",
92
+ dark: "dark:text-zinc-400"
93
+ }
94
+ }
95
+ },
96
+ divider: {
97
+ base: "w-full h-px my-4",
98
+ color: {
99
+ light: "bg-zinc-200",
100
+ dark: "dark:bg-zinc-700"
101
+ }
102
+ },
103
+ section: {
104
+ base: "mb-6",
105
+ title: {
106
+ base: "text-sm font-medium uppercase tracking-wider mb-3",
107
+ color: {
108
+ light: "text-zinc-500",
109
+ dark: "dark:text-zinc-400"
110
+ }
111
+ }
112
+ },
113
+ animation: {
114
+ field: {
115
+ enter: {
116
+ duration: 0.3,
117
+ ease: "power2.out",
118
+ stagger: 0.05
119
+ },
120
+ exit: {
121
+ duration: 0.2,
122
+ ease: "power2.in"
123
+ },
124
+ error: {
125
+ duration: 0.4,
126
+ ease: "elastic.out(1, 0.5)"
127
+ }
128
+ },
129
+ submit: {
130
+ duration: 0.2,
131
+ ease: "power2.out"
132
+ }
133
+ }
134
+ };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,5 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ export function cn(...inputs) {
4
+ return twMerge(clsx(inputs));
5
+ }