@nccirtu/tablefy 0.8.4 → 0.9.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 (243) hide show
  1. package/README.md +224 -200
  2. package/dist/columns/forms/builders/actions-builder.d.ts +14 -0
  3. package/dist/columns/forms/builders/form-schema.d.ts +35 -0
  4. package/dist/columns/forms/builders/index.d.ts +5 -0
  5. package/dist/columns/forms/builders/section-builder.d.ts +16 -0
  6. package/dist/columns/forms/builders/tab-builder.d.ts +16 -0
  7. package/dist/columns/forms/builders/wizard-builder.d.ts +17 -0
  8. package/dist/columns/forms/components/field-renderer.d.ts +12 -0
  9. package/dist/columns/forms/components/form-actions.d.ts +9 -0
  10. package/dist/columns/forms/components/form-renderer.d.ts +14 -0
  11. package/dist/columns/forms/components/grid-layout.d.ts +7 -0
  12. package/dist/columns/forms/components/index.d.ts +9 -0
  13. package/dist/columns/forms/components/section-renderer.d.ts +14 -0
  14. package/dist/columns/forms/components/tab-renderer.d.ts +15 -0
  15. package/dist/columns/forms/components/wizard-renderer.d.ts +17 -0
  16. package/dist/columns/forms/fields/base-field.d.ts +24 -0
  17. package/dist/columns/forms/fields/checkbox-group.d.ts +12 -0
  18. package/dist/columns/forms/fields/checkbox.d.ts +9 -0
  19. package/dist/columns/forms/fields/date-picker.d.ts +15 -0
  20. package/dist/columns/forms/fields/file-upload.d.ts +17 -0
  21. package/dist/columns/forms/fields/hidden.d.ts +9 -0
  22. package/dist/columns/forms/fields/index.d.ts +12 -0
  23. package/dist/columns/forms/fields/radio-group.d.ts +14 -0
  24. package/dist/columns/forms/fields/repeater.d.ts +21 -0
  25. package/dist/columns/forms/fields/select.d.ts +16 -0
  26. package/dist/columns/forms/fields/text-input.d.ts +20 -0
  27. package/dist/columns/forms/fields/textarea.d.ts +14 -0
  28. package/dist/columns/forms/fields/toggle.d.ts +11 -0
  29. package/dist/columns/forms/index.d.ts +26 -0
  30. package/dist/columns/forms/types/actions.d.ts +11 -0
  31. package/dist/columns/forms/types/field.d.ts +98 -0
  32. package/dist/columns/forms/types/form.d.ts +37 -0
  33. package/dist/columns/forms/types/index.d.ts +4 -0
  34. package/dist/columns/forms/types/layout.d.ts +31 -0
  35. package/dist/columns/index.d.ts +2 -0
  36. package/dist/columns/inertia/index.d.ts +4 -0
  37. package/dist/columns/inertia/precognition.d.ts +6 -0
  38. package/dist/columns/inertia/types.d.ts +63 -0
  39. package/dist/columns/inertia/use-inertia-form.d.ts +2 -0
  40. package/dist/columns/inertia/use-server-table.d.ts +2 -0
  41. package/dist/forms/builders/actions-builder.d.ts +14 -0
  42. package/dist/forms/builders/empty-state.d.ts +46 -0
  43. package/dist/forms/builders/form-schema.d.ts +35 -0
  44. package/dist/forms/builders/index.d.ts +2 -0
  45. package/dist/forms/builders/section-builder.d.ts +16 -0
  46. package/dist/forms/builders/tab-builder.d.ts +16 -0
  47. package/dist/forms/builders/table-schema.d.ts +45 -0
  48. package/dist/forms/builders/wizard-builder.d.ts +17 -0
  49. package/dist/forms/columns/actions-column.d.ts +26 -0
  50. package/dist/forms/columns/avatar-group-column.d.ts +38 -0
  51. package/dist/forms/columns/badge-column.d.ts +29 -0
  52. package/dist/forms/columns/base-column.d.ts +21 -0
  53. package/dist/forms/columns/button-column.d.ts +14 -0
  54. package/dist/forms/columns/checkbox-column.d.ts +5 -0
  55. package/dist/forms/columns/date-column.d.ts +24 -0
  56. package/dist/forms/columns/dropdown-column.d.ts +17 -0
  57. package/dist/forms/columns/enum-column.d.ts +52 -0
  58. package/dist/forms/columns/icon-column.d.ts +58 -0
  59. package/dist/forms/columns/image-column.d.ts +21 -0
  60. package/dist/forms/columns/index.d.ts +18 -0
  61. package/dist/forms/columns/input-column.d.ts +27 -0
  62. package/dist/forms/columns/link-column.d.ts +27 -0
  63. package/dist/forms/columns/number-column.d.ts +23 -0
  64. package/dist/forms/columns/progress-column.d.ts +30 -0
  65. package/dist/forms/columns/select-column.d.ts +24 -0
  66. package/dist/forms/columns/text-column.d.ts +14 -0
  67. package/dist/forms/columns/types.d.ts +46 -0
  68. package/dist/forms/components/field-renderer.d.ts +12 -0
  69. package/dist/forms/components/form-actions.d.ts +9 -0
  70. package/dist/forms/components/form-renderer.d.ts +14 -0
  71. package/dist/forms/components/grid-layout.d.ts +7 -0
  72. package/dist/forms/components/index.d.ts +9 -0
  73. package/dist/forms/components/section-renderer.d.ts +14 -0
  74. package/dist/forms/components/tab-renderer.d.ts +15 -0
  75. package/dist/forms/components/wizard-renderer.d.ts +17 -0
  76. package/dist/forms/confirm/ConfirmProvider.d.ts +6 -0
  77. package/dist/forms/confirm/confirm.d.ts +3 -0
  78. package/dist/forms/confirm/index.d.ts +3 -0
  79. package/dist/forms/confirm/types.d.ts +10 -0
  80. package/dist/forms/fields/base-field.d.ts +24 -0
  81. package/dist/forms/fields/checkbox-group.d.ts +12 -0
  82. package/dist/forms/fields/checkbox.d.ts +9 -0
  83. package/dist/forms/fields/date-picker.d.ts +15 -0
  84. package/dist/forms/fields/file-upload.d.ts +17 -0
  85. package/dist/forms/fields/hidden.d.ts +9 -0
  86. package/dist/forms/fields/index.d.ts +12 -0
  87. package/dist/forms/fields/radio-group.d.ts +14 -0
  88. package/dist/forms/fields/repeater.d.ts +21 -0
  89. package/dist/forms/fields/select.d.ts +16 -0
  90. package/dist/forms/fields/text-input.d.ts +20 -0
  91. package/dist/forms/fields/textarea.d.ts +14 -0
  92. package/dist/forms/fields/toggle.d.ts +11 -0
  93. package/dist/forms/forms/builders/actions-builder.d.ts +14 -0
  94. package/dist/forms/forms/builders/form-schema.d.ts +35 -0
  95. package/dist/forms/forms/builders/index.d.ts +5 -0
  96. package/dist/forms/forms/builders/section-builder.d.ts +16 -0
  97. package/dist/forms/forms/builders/tab-builder.d.ts +16 -0
  98. package/dist/forms/forms/builders/wizard-builder.d.ts +17 -0
  99. package/dist/forms/forms/components/field-renderer.d.ts +12 -0
  100. package/dist/forms/forms/components/form-actions.d.ts +9 -0
  101. package/dist/forms/forms/components/form-renderer.d.ts +14 -0
  102. package/dist/forms/forms/components/grid-layout.d.ts +7 -0
  103. package/dist/forms/forms/components/index.d.ts +9 -0
  104. package/dist/forms/forms/components/section-renderer.d.ts +14 -0
  105. package/dist/forms/forms/components/tab-renderer.d.ts +15 -0
  106. package/dist/forms/forms/components/wizard-renderer.d.ts +17 -0
  107. package/dist/forms/forms/fields/base-field.d.ts +24 -0
  108. package/dist/forms/forms/fields/checkbox-group.d.ts +12 -0
  109. package/dist/forms/forms/fields/checkbox.d.ts +9 -0
  110. package/dist/forms/forms/fields/date-picker.d.ts +15 -0
  111. package/dist/forms/forms/fields/file-upload.d.ts +17 -0
  112. package/dist/forms/forms/fields/hidden.d.ts +9 -0
  113. package/dist/forms/forms/fields/index.d.ts +12 -0
  114. package/dist/forms/forms/fields/radio-group.d.ts +14 -0
  115. package/dist/forms/forms/fields/repeater.d.ts +21 -0
  116. package/dist/forms/forms/fields/select.d.ts +16 -0
  117. package/dist/forms/forms/fields/text-input.d.ts +20 -0
  118. package/dist/forms/forms/fields/textarea.d.ts +14 -0
  119. package/dist/forms/forms/fields/toggle.d.ts +11 -0
  120. package/dist/forms/forms/index.d.ts +26 -0
  121. package/dist/forms/forms/types/actions.d.ts +11 -0
  122. package/dist/forms/forms/types/field.d.ts +98 -0
  123. package/dist/forms/forms/types/form.d.ts +37 -0
  124. package/dist/forms/forms/types/index.d.ts +4 -0
  125. package/dist/forms/forms/types/layout.d.ts +31 -0
  126. package/dist/forms/index.d.ts +25 -0
  127. package/dist/forms/index.esm.js +1052 -0
  128. package/dist/forms/index.esm.js.map +1 -0
  129. package/dist/forms/index.js +1077 -0
  130. package/dist/forms/index.js.map +1 -0
  131. package/dist/forms/inertia/index.d.ts +4 -0
  132. package/dist/forms/inertia/precognition.d.ts +6 -0
  133. package/dist/forms/inertia/types.d.ts +63 -0
  134. package/dist/forms/inertia/use-inertia-form.d.ts +2 -0
  135. package/dist/forms/inertia/use-server-table.d.ts +2 -0
  136. package/dist/forms/tablefy/avatar-list.d.ts +15 -0
  137. package/dist/forms/tablefy/data-table-empty.d.ts +8 -0
  138. package/dist/forms/tablefy/data-table-header.d.ts +17 -0
  139. package/dist/forms/tablefy/data-table-pagination.d.ts +9 -0
  140. package/dist/forms/tablefy/data-table-schema.d.ts +1 -0
  141. package/dist/forms/tablefy/data-table.d.ts +13 -0
  142. package/dist/forms/tablefy/index.d.ts +6 -0
  143. package/dist/forms/types/actions.d.ts +21 -0
  144. package/dist/forms/types/empty-state.d.ts +18 -0
  145. package/dist/forms/types/field.d.ts +98 -0
  146. package/dist/forms/types/filters.d.ts +25 -0
  147. package/dist/forms/types/form.d.ts +37 -0
  148. package/dist/forms/types/index.d.ts +4 -0
  149. package/dist/forms/types/layout.d.ts +31 -0
  150. package/dist/forms/types/table.d.ts +42 -0
  151. package/dist/forms/utils.d.ts +1 -0
  152. package/dist/index.d.ts +2 -0
  153. package/dist/index.esm.js +1050 -9
  154. package/dist/index.esm.js.map +1 -1
  155. package/dist/index.js +1058 -0
  156. package/dist/index.js.map +1 -1
  157. package/dist/inertia/builders/empty-state.d.ts +46 -0
  158. package/dist/inertia/builders/index.d.ts +2 -0
  159. package/dist/inertia/builders/table-schema.d.ts +45 -0
  160. package/dist/inertia/columns/actions-column.d.ts +26 -0
  161. package/dist/inertia/columns/avatar-group-column.d.ts +38 -0
  162. package/dist/inertia/columns/badge-column.d.ts +29 -0
  163. package/dist/inertia/columns/base-column.d.ts +21 -0
  164. package/dist/inertia/columns/button-column.d.ts +14 -0
  165. package/dist/inertia/columns/checkbox-column.d.ts +5 -0
  166. package/dist/inertia/columns/date-column.d.ts +24 -0
  167. package/dist/inertia/columns/dropdown-column.d.ts +17 -0
  168. package/dist/inertia/columns/enum-column.d.ts +52 -0
  169. package/dist/inertia/columns/icon-column.d.ts +58 -0
  170. package/dist/inertia/columns/image-column.d.ts +21 -0
  171. package/dist/inertia/columns/index.d.ts +18 -0
  172. package/dist/inertia/columns/input-column.d.ts +27 -0
  173. package/dist/inertia/columns/link-column.d.ts +27 -0
  174. package/dist/inertia/columns/number-column.d.ts +23 -0
  175. package/dist/inertia/columns/progress-column.d.ts +30 -0
  176. package/dist/inertia/columns/select-column.d.ts +24 -0
  177. package/dist/inertia/columns/text-column.d.ts +14 -0
  178. package/dist/inertia/columns/types.d.ts +46 -0
  179. package/dist/inertia/confirm/ConfirmProvider.d.ts +6 -0
  180. package/dist/inertia/confirm/confirm.d.ts +3 -0
  181. package/dist/inertia/confirm/index.d.ts +3 -0
  182. package/dist/inertia/confirm/types.d.ts +10 -0
  183. package/dist/inertia/forms/builders/actions-builder.d.ts +14 -0
  184. package/dist/inertia/forms/builders/form-schema.d.ts +35 -0
  185. package/dist/inertia/forms/builders/index.d.ts +5 -0
  186. package/dist/inertia/forms/builders/section-builder.d.ts +16 -0
  187. package/dist/inertia/forms/builders/tab-builder.d.ts +16 -0
  188. package/dist/inertia/forms/builders/wizard-builder.d.ts +17 -0
  189. package/dist/inertia/forms/components/field-renderer.d.ts +12 -0
  190. package/dist/inertia/forms/components/form-actions.d.ts +9 -0
  191. package/dist/inertia/forms/components/form-renderer.d.ts +14 -0
  192. package/dist/inertia/forms/components/grid-layout.d.ts +7 -0
  193. package/dist/inertia/forms/components/index.d.ts +9 -0
  194. package/dist/inertia/forms/components/section-renderer.d.ts +14 -0
  195. package/dist/inertia/forms/components/tab-renderer.d.ts +15 -0
  196. package/dist/inertia/forms/components/wizard-renderer.d.ts +17 -0
  197. package/dist/inertia/forms/fields/base-field.d.ts +24 -0
  198. package/dist/inertia/forms/fields/checkbox-group.d.ts +12 -0
  199. package/dist/inertia/forms/fields/checkbox.d.ts +9 -0
  200. package/dist/inertia/forms/fields/date-picker.d.ts +15 -0
  201. package/dist/inertia/forms/fields/file-upload.d.ts +17 -0
  202. package/dist/inertia/forms/fields/hidden.d.ts +9 -0
  203. package/dist/inertia/forms/fields/index.d.ts +12 -0
  204. package/dist/inertia/forms/fields/radio-group.d.ts +14 -0
  205. package/dist/inertia/forms/fields/repeater.d.ts +21 -0
  206. package/dist/inertia/forms/fields/select.d.ts +16 -0
  207. package/dist/inertia/forms/fields/text-input.d.ts +20 -0
  208. package/dist/inertia/forms/fields/textarea.d.ts +14 -0
  209. package/dist/inertia/forms/fields/toggle.d.ts +11 -0
  210. package/dist/inertia/forms/index.d.ts +26 -0
  211. package/dist/inertia/forms/types/actions.d.ts +11 -0
  212. package/dist/inertia/forms/types/field.d.ts +98 -0
  213. package/dist/inertia/forms/types/form.d.ts +37 -0
  214. package/dist/inertia/forms/types/index.d.ts +4 -0
  215. package/dist/inertia/forms/types/layout.d.ts +31 -0
  216. package/dist/inertia/index.d.ts +25 -0
  217. package/dist/inertia/index.esm.js +149 -0
  218. package/dist/inertia/index.esm.js.map +1 -0
  219. package/dist/inertia/index.js +153 -0
  220. package/dist/inertia/index.js.map +1 -0
  221. package/dist/inertia/inertia/index.d.ts +4 -0
  222. package/dist/inertia/inertia/precognition.d.ts +6 -0
  223. package/dist/inertia/inertia/types.d.ts +63 -0
  224. package/dist/inertia/inertia/use-inertia-form.d.ts +2 -0
  225. package/dist/inertia/inertia/use-server-table.d.ts +2 -0
  226. package/dist/inertia/precognition.d.ts +6 -0
  227. package/dist/inertia/tablefy/avatar-list.d.ts +15 -0
  228. package/dist/inertia/tablefy/data-table-empty.d.ts +8 -0
  229. package/dist/inertia/tablefy/data-table-header.d.ts +17 -0
  230. package/dist/inertia/tablefy/data-table-pagination.d.ts +9 -0
  231. package/dist/inertia/tablefy/data-table-schema.d.ts +1 -0
  232. package/dist/inertia/tablefy/data-table.d.ts +13 -0
  233. package/dist/inertia/tablefy/index.d.ts +6 -0
  234. package/dist/inertia/types/actions.d.ts +21 -0
  235. package/dist/inertia/types/empty-state.d.ts +18 -0
  236. package/dist/inertia/types/filters.d.ts +25 -0
  237. package/dist/inertia/types/index.d.ts +4 -0
  238. package/dist/inertia/types/table.d.ts +42 -0
  239. package/dist/inertia/types.d.ts +63 -0
  240. package/dist/inertia/use-inertia-form.d.ts +2 -0
  241. package/dist/inertia/use-server-table.d.ts +2 -0
  242. package/dist/inertia/utils.d.ts +1 -0
  243. package/package.json +39 -13
@@ -0,0 +1,1077 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var input = require('@/components/ui/input');
5
+ var utils = require('@/lib/utils');
6
+ var textarea = require('@/components/ui/textarea');
7
+ var select = require('@/components/ui/select');
8
+ var checkbox = require('@/components/ui/checkbox');
9
+ var _switch = require('@/components/ui/switch');
10
+ var radioGroup = require('@/components/ui/radio-group');
11
+ var label = require('@/components/ui/label');
12
+ var button = require('@/components/ui/button');
13
+ var calendar = require('@/components/ui/calendar');
14
+ var popover = require('@/components/ui/popover');
15
+ var lucideReact = require('lucide-react');
16
+ var react = require('react');
17
+ var card = require('@/components/ui/card');
18
+ var tabs = require('@/components/ui/tabs');
19
+
20
+ class ActionsBuilder {
21
+ actionsList = [];
22
+ submit(opts = {}) {
23
+ this.actionsList.push({
24
+ type: "submit",
25
+ label: opts.label || "Submit",
26
+ variant: opts.variant || "default",
27
+ ...opts,
28
+ });
29
+ return this;
30
+ }
31
+ cancel(opts = {}) {
32
+ this.actionsList.push({
33
+ type: "cancel",
34
+ label: opts.label || "Cancel",
35
+ variant: opts.variant || "outline",
36
+ ...opts,
37
+ });
38
+ return this;
39
+ }
40
+ custom(opts) {
41
+ this.actionsList.push({ ...opts, type: "custom" });
42
+ return this;
43
+ }
44
+ build() {
45
+ return [...this.actionsList];
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Form Schema Builder
51
+ * Fluent API for building complete form configurations
52
+ */
53
+ class FormSchema {
54
+ fieldBuilders = [];
55
+ schemaConfig = {};
56
+ static make() {
57
+ return new FormSchema();
58
+ }
59
+ // --- Configuration ---
60
+ title(title) {
61
+ this.schemaConfig.title = title;
62
+ return this;
63
+ }
64
+ description(description) {
65
+ this.schemaConfig.description = description;
66
+ return this;
67
+ }
68
+ columns(columns) {
69
+ this.schemaConfig.columns = columns;
70
+ return this;
71
+ }
72
+ bordered(bordered = true) {
73
+ this.schemaConfig.bordered = bordered;
74
+ return this;
75
+ }
76
+ spacing(spacing) {
77
+ this.schemaConfig.spacing = spacing;
78
+ return this;
79
+ }
80
+ disabled(disabled) {
81
+ this.schemaConfig.disabled = disabled;
82
+ return this;
83
+ }
84
+ // --- Fields ---
85
+ fields(...builders) {
86
+ this.fieldBuilders.push(...builders);
87
+ return this;
88
+ }
89
+ // --- Layout ---
90
+ sections(...sections) {
91
+ this.schemaConfig.sections = sections.map((s) => s.build());
92
+ return this;
93
+ }
94
+ tabs(...tabs) {
95
+ this.schemaConfig.tabs = tabs.map((t) => t.build());
96
+ return this;
97
+ }
98
+ wizard(...steps) {
99
+ this.schemaConfig.wizardSteps = steps.map((s) => s.build());
100
+ return this;
101
+ }
102
+ // --- Actions ---
103
+ actions(fn) {
104
+ const builder = new ActionsBuilder();
105
+ this.schemaConfig.actions = fn(builder).build();
106
+ return this;
107
+ }
108
+ actionsPosition(position) {
109
+ this.schemaConfig.actionsPosition = position;
110
+ return this;
111
+ }
112
+ // --- Build ---
113
+ build() {
114
+ const fields = this.fieldBuilders.map((b) => b.build());
115
+ return {
116
+ fields,
117
+ config: {
118
+ ...this.schemaConfig,
119
+ fields,
120
+ },
121
+ };
122
+ }
123
+ }
124
+
125
+ class SectionBuilder {
126
+ sectionConfig;
127
+ constructor(title) {
128
+ this.sectionConfig = {
129
+ id: title.toLowerCase().replace(/\s+/g, "-"),
130
+ title,
131
+ fields: [],
132
+ columns: 1,
133
+ collapsible: false,
134
+ collapsed: false,
135
+ };
136
+ }
137
+ static make(title) {
138
+ return new SectionBuilder(title);
139
+ }
140
+ id(id) {
141
+ this.sectionConfig.id = id;
142
+ return this;
143
+ }
144
+ description(description) {
145
+ this.sectionConfig.description = description;
146
+ return this;
147
+ }
148
+ fields(fields) {
149
+ this.sectionConfig.fields = fields;
150
+ return this;
151
+ }
152
+ columns(columns) {
153
+ this.sectionConfig.columns = columns;
154
+ return this;
155
+ }
156
+ collapsible(collapsible = true) {
157
+ this.sectionConfig.collapsible = collapsible;
158
+ return this;
159
+ }
160
+ collapsed(collapsed = true) {
161
+ this.sectionConfig.collapsed = collapsed;
162
+ this.sectionConfig.collapsible = true;
163
+ return this;
164
+ }
165
+ icon(icon) {
166
+ this.sectionConfig.icon = icon;
167
+ return this;
168
+ }
169
+ hidden(fn) {
170
+ this.sectionConfig.hidden = fn;
171
+ return this;
172
+ }
173
+ build() {
174
+ return { ...this.sectionConfig };
175
+ }
176
+ }
177
+
178
+ class TabBuilder {
179
+ tabConfig;
180
+ constructor(label) {
181
+ this.tabConfig = {
182
+ id: label.toLowerCase().replace(/\s+/g, "-"),
183
+ label,
184
+ };
185
+ }
186
+ static make(label) {
187
+ return new TabBuilder(label);
188
+ }
189
+ id(id) {
190
+ this.tabConfig.id = id;
191
+ return this;
192
+ }
193
+ icon(icon) {
194
+ this.tabConfig.icon = icon;
195
+ return this;
196
+ }
197
+ fields(fields) {
198
+ this.tabConfig.fields = fields;
199
+ return this;
200
+ }
201
+ sections(...sections) {
202
+ this.tabConfig.sections = sections.map((s) => s.build());
203
+ return this;
204
+ }
205
+ badge(badge) {
206
+ this.tabConfig.badge = badge;
207
+ return this;
208
+ }
209
+ disabled(fn) {
210
+ this.tabConfig.disabled = fn;
211
+ return this;
212
+ }
213
+ build() {
214
+ return { ...this.tabConfig };
215
+ }
216
+ }
217
+
218
+ class WizardStep {
219
+ stepConfig;
220
+ constructor(label) {
221
+ this.stepConfig = {
222
+ id: label.toLowerCase().replace(/\s+/g, "-"),
223
+ label,
224
+ };
225
+ }
226
+ static make(label) {
227
+ return new WizardStep(label);
228
+ }
229
+ id(id) {
230
+ this.stepConfig.id = id;
231
+ return this;
232
+ }
233
+ description(description) {
234
+ this.stepConfig.description = description;
235
+ return this;
236
+ }
237
+ icon(icon) {
238
+ this.stepConfig.icon = icon;
239
+ return this;
240
+ }
241
+ fields(fields) {
242
+ this.stepConfig.fields = fields;
243
+ return this;
244
+ }
245
+ sections(...sections) {
246
+ this.stepConfig.sections = sections.map((s) => s.build());
247
+ return this;
248
+ }
249
+ canProceed(fn) {
250
+ this.stepConfig.canProceed = fn;
251
+ return this;
252
+ }
253
+ beforeNext(fn) {
254
+ this.stepConfig.beforeNext = fn;
255
+ return this;
256
+ }
257
+ build() {
258
+ return { ...this.stepConfig };
259
+ }
260
+ }
261
+
262
+ class BaseField {
263
+ config;
264
+ constructor(name) {
265
+ this.config = {
266
+ name,
267
+ required: false,
268
+ disabled: false,
269
+ readOnly: false,
270
+ hidden: false,
271
+ columnSpan: 1,
272
+ rules: [],
273
+ dependsOn: [],
274
+ };
275
+ }
276
+ // --- Fluent API ---
277
+ label(label) {
278
+ this.config.label = label;
279
+ return this;
280
+ }
281
+ placeholder(placeholder) {
282
+ this.config.placeholder = placeholder;
283
+ return this;
284
+ }
285
+ helperText(text) {
286
+ this.config.helperText = text;
287
+ return this;
288
+ }
289
+ required(required = true) {
290
+ this.config.required = required;
291
+ if (required &&
292
+ !this.config.rules?.some((r) => r.type === "required")) {
293
+ this.config.rules = [
294
+ ...(this.config.rules || []),
295
+ {
296
+ type: "required",
297
+ message: `${this.config.label || this.config.name} is required`,
298
+ },
299
+ ];
300
+ }
301
+ return this;
302
+ }
303
+ disabled(disabled = true) {
304
+ this.config.disabled = disabled;
305
+ return this;
306
+ }
307
+ readOnly(readOnly = true) {
308
+ this.config.readOnly = readOnly;
309
+ return this;
310
+ }
311
+ hidden(hidden = true) {
312
+ this.config.hidden = hidden;
313
+ return this;
314
+ }
315
+ default(value) {
316
+ this.config.defaultValue = value;
317
+ return this;
318
+ }
319
+ columnSpan(span) {
320
+ this.config.columnSpan = span;
321
+ return this;
322
+ }
323
+ className(className) {
324
+ this.config.className = className;
325
+ return this;
326
+ }
327
+ rules(rules) {
328
+ this.config.rules = [...(this.config.rules || []), ...rules];
329
+ return this;
330
+ }
331
+ zodSchema(schema) {
332
+ this.config.zodSchema = schema;
333
+ return this;
334
+ }
335
+ dependsOn(field, condition, effect = "show", effectValue) {
336
+ this.config.dependsOn = [
337
+ ...(this.config.dependsOn || []),
338
+ { field, condition, effect, effectValue },
339
+ ];
340
+ return this;
341
+ }
342
+ reactive(reactive = true) {
343
+ this.config.reactive = reactive;
344
+ return this;
345
+ }
346
+ // --- Build ---
347
+ build() {
348
+ return {
349
+ name: this.config.name,
350
+ type: this.fieldType,
351
+ config: { ...this.config },
352
+ render: (props) => this.renderField(props),
353
+ };
354
+ }
355
+ }
356
+
357
+ class TextInput extends BaseField {
358
+ fieldType = "text";
359
+ static make(name) {
360
+ return new TextInput(name);
361
+ }
362
+ type(type) {
363
+ this.config.type = type;
364
+ return this;
365
+ }
366
+ email() {
367
+ return this.type("email");
368
+ }
369
+ password() {
370
+ return this.type("password");
371
+ }
372
+ number() {
373
+ return this.type("number");
374
+ }
375
+ url() {
376
+ return this.type("url");
377
+ }
378
+ tel() {
379
+ return this.type("tel");
380
+ }
381
+ minLength(min) {
382
+ this.config.minLength = min;
383
+ this.config.rules = [
384
+ ...(this.config.rules || []),
385
+ {
386
+ type: "min",
387
+ value: min,
388
+ message: `${this.config.label || this.config.name} must be at least ${min} characters`,
389
+ },
390
+ ];
391
+ return this;
392
+ }
393
+ maxLength(max) {
394
+ this.config.maxLength = max;
395
+ this.config.rules = [
396
+ ...(this.config.rules || []),
397
+ {
398
+ type: "max",
399
+ value: max,
400
+ message: `${this.config.label || this.config.name} must be at most ${max} characters`,
401
+ },
402
+ ];
403
+ return this;
404
+ }
405
+ prefix(prefix) {
406
+ this.config.prefix = prefix;
407
+ return this;
408
+ }
409
+ suffix(suffix) {
410
+ this.config.suffix = suffix;
411
+ return this;
412
+ }
413
+ autocomplete(value) {
414
+ this.config.autocomplete = value;
415
+ return this;
416
+ }
417
+ renderField({ value, onChange, onBlur, error, disabled, }) {
418
+ const { type, placeholder, maxLength, readOnly, autocomplete, className, prefix, suffix, } = this.config;
419
+ const input$1 = (jsxRuntime.jsx(input.Input, { type: type || "text", value: value ?? "", onChange: (e) => onChange(type === "number" ? Number(e.target.value) : e.target.value), onBlur: onBlur, placeholder: placeholder, maxLength: maxLength, disabled: disabled, readOnly: readOnly, autoComplete: autocomplete, className: utils.cn(error && "border-destructive", className) }));
420
+ if (prefix || suffix) {
421
+ return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [prefix && (jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: prefix })), input$1, suffix && (jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: suffix }))] }));
422
+ }
423
+ return input$1;
424
+ }
425
+ }
426
+
427
+ class Textarea extends BaseField {
428
+ fieldType = "textarea";
429
+ constructor(name) {
430
+ super(name);
431
+ this.config.rows = 3;
432
+ }
433
+ static make(name) {
434
+ return new Textarea(name);
435
+ }
436
+ rows(rows) {
437
+ this.config.rows = rows;
438
+ return this;
439
+ }
440
+ minLength(min) {
441
+ this.config.minLength = min;
442
+ this.config.rules = [
443
+ ...(this.config.rules || []),
444
+ {
445
+ type: "min",
446
+ value: min,
447
+ message: `${this.config.label || this.config.name} must be at least ${min} characters`,
448
+ },
449
+ ];
450
+ return this;
451
+ }
452
+ maxLength(max) {
453
+ this.config.maxLength = max;
454
+ this.config.rules = [
455
+ ...(this.config.rules || []),
456
+ {
457
+ type: "max",
458
+ value: max,
459
+ message: `${this.config.label || this.config.name} must be at most ${max} characters`,
460
+ },
461
+ ];
462
+ return this;
463
+ }
464
+ autoResize(autoResize = true) {
465
+ this.config.autoResize = autoResize;
466
+ return this;
467
+ }
468
+ renderField({ value, onChange, onBlur, error, disabled, }) {
469
+ const { placeholder, rows, maxLength, readOnly, className } = this.config;
470
+ return (jsxRuntime.jsx(textarea.Textarea, { value: value ?? "", onChange: (e) => onChange(e.target.value), onBlur: onBlur, placeholder: placeholder, rows: rows, maxLength: maxLength, disabled: disabled, readOnly: readOnly, className: utils.cn(error && "border-destructive", className) }));
471
+ }
472
+ }
473
+
474
+ class Select extends BaseField {
475
+ fieldType = "select";
476
+ constructor(name) {
477
+ super(name);
478
+ this.config.options = [];
479
+ this.config.multiple = false;
480
+ this.config.searchable = false;
481
+ this.config.clearable = false;
482
+ }
483
+ static make(name) {
484
+ return new Select(name);
485
+ }
486
+ options(options) {
487
+ this.config.options = options;
488
+ return this;
489
+ }
490
+ multiple(multiple = true) {
491
+ this.config.multiple = multiple;
492
+ return this;
493
+ }
494
+ searchable(searchable = true) {
495
+ this.config.searchable = searchable;
496
+ return this;
497
+ }
498
+ clearable(clearable = true) {
499
+ this.config.clearable = clearable;
500
+ return this;
501
+ }
502
+ maxItems(max) {
503
+ this.config.maxItems = max;
504
+ return this;
505
+ }
506
+ loadOptions(fn) {
507
+ this.config.loadOptions = fn;
508
+ return this;
509
+ }
510
+ renderField({ value, onChange, error, disabled, data, }) {
511
+ const cfg = this.config;
512
+ const resolvedOptions = typeof cfg.options === "function" ? cfg.options(data) : cfg.options;
513
+ return (jsxRuntime.jsxs(select.Select, { value: value ?? "", onValueChange: onChange, disabled: disabled, children: [jsxRuntime.jsx(select.SelectTrigger, { className: utils.cn(error && "border-destructive", cfg.className), children: jsxRuntime.jsx(select.SelectValue, { placeholder: cfg.placeholder || "Select..." }) }), jsxRuntime.jsx(select.SelectContent, { children: resolvedOptions.map((opt) => (jsxRuntime.jsx(select.SelectItem, { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value))) })] }));
514
+ }
515
+ }
516
+
517
+ class Checkbox extends BaseField {
518
+ fieldType = "checkbox";
519
+ static make(name) {
520
+ return new Checkbox(name);
521
+ }
522
+ renderField({ value, onChange, error, disabled, }) {
523
+ const { className } = this.config;
524
+ return (jsxRuntime.jsxs("div", { className: utils.cn("flex items-center space-x-2", className), children: [jsxRuntime.jsx(checkbox.Checkbox, { id: this.config.name, checked: !!value, onCheckedChange: (checked) => onChange(!!checked), disabled: disabled, className: utils.cn(error && "border-destructive") }), this.config.label && (jsxRuntime.jsx("label", { htmlFor: this.config.name, className: utils.cn("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", error && "text-destructive"), children: this.config.label }))] }));
525
+ }
526
+ }
527
+
528
+ class Toggle extends BaseField {
529
+ fieldType = "toggle";
530
+ static make(name) {
531
+ return new Toggle(name);
532
+ }
533
+ onLabel(label) {
534
+ this.config.onLabel = label;
535
+ return this;
536
+ }
537
+ offLabel(label) {
538
+ this.config.offLabel = label;
539
+ return this;
540
+ }
541
+ renderField({ value, onChange, error, disabled, }) {
542
+ const { onLabel, offLabel, className } = this.config;
543
+ const displayLabel = value ? onLabel : offLabel;
544
+ return (jsxRuntime.jsxs("div", { className: utils.cn("flex items-center space-x-2", className), children: [jsxRuntime.jsx(_switch.Switch, { id: this.config.name, checked: !!value, onCheckedChange: (checked) => onChange(checked), disabled: disabled, className: utils.cn(error && "border-destructive") }), displayLabel && (jsxRuntime.jsx("label", { htmlFor: this.config.name, className: "text-sm text-muted-foreground", children: displayLabel }))] }));
545
+ }
546
+ }
547
+
548
+ class RadioGroup extends BaseField {
549
+ fieldType = "radio-group";
550
+ constructor(name) {
551
+ super(name);
552
+ this.config.options = [];
553
+ this.config.orientation = "vertical";
554
+ }
555
+ static make(name) {
556
+ return new RadioGroup(name);
557
+ }
558
+ options(options) {
559
+ this.config.options = options;
560
+ return this;
561
+ }
562
+ orientation(orientation) {
563
+ this.config.orientation = orientation;
564
+ return this;
565
+ }
566
+ horizontal() {
567
+ return this.orientation("horizontal");
568
+ }
569
+ vertical() {
570
+ return this.orientation("vertical");
571
+ }
572
+ renderField({ value, onChange, error, disabled, }) {
573
+ const cfg = this.config;
574
+ const isHorizontal = cfg.orientation === "horizontal";
575
+ return (jsxRuntime.jsx(radioGroup.RadioGroup, { value: value ?? "", onValueChange: onChange, disabled: disabled, className: utils.cn(isHorizontal ? "flex flex-row gap-4" : "flex flex-col gap-2", cfg.className), children: cfg.options.map((opt) => (jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [jsxRuntime.jsx(radioGroup.RadioGroupItem, { value: opt.value, id: `${cfg.name}-${opt.value}`, disabled: opt.disabled, className: utils.cn(error && "border-destructive") }), jsxRuntime.jsx(label.Label, { htmlFor: `${cfg.name}-${opt.value}`, className: "text-sm font-normal", children: opt.label })] }, opt.value))) }));
576
+ }
577
+ }
578
+
579
+ class DatePicker extends BaseField {
580
+ fieldType = "date-picker";
581
+ constructor(name) {
582
+ super(name);
583
+ this.config.format = "PPP";
584
+ this.config.includeTime = false;
585
+ this.config.locale = "en-US";
586
+ }
587
+ static make(name) {
588
+ return new DatePicker(name);
589
+ }
590
+ minDate(date) {
591
+ this.config.minDate = date;
592
+ return this;
593
+ }
594
+ maxDate(date) {
595
+ this.config.maxDate = date;
596
+ return this;
597
+ }
598
+ format(format) {
599
+ this.config.format = format;
600
+ return this;
601
+ }
602
+ includeTime(includeTime = true) {
603
+ this.config.includeTime = includeTime;
604
+ if (includeTime) {
605
+ this.fieldType = "date-time-picker";
606
+ }
607
+ return this;
608
+ }
609
+ locale(locale) {
610
+ this.config.locale = locale;
611
+ return this;
612
+ }
613
+ renderField({ value, onChange, error, disabled, data, }) {
614
+ const { placeholder, className, locale } = this.config;
615
+ const resolvedMinDate = typeof this.config.minDate === "function"
616
+ ? this.config.minDate(data)
617
+ : this.config.minDate;
618
+ const resolvedMaxDate = typeof this.config.maxDate === "function"
619
+ ? this.config.maxDate(data)
620
+ : this.config.maxDate;
621
+ const dateValue = value ? new Date(value) : undefined;
622
+ const formatDate = (date) => {
623
+ return date.toLocaleDateString(locale || "en-US", {
624
+ year: "numeric",
625
+ month: "long",
626
+ day: "numeric",
627
+ });
628
+ };
629
+ return (jsxRuntime.jsxs(popover.Popover, { children: [jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(button.Button, { variant: "outline", disabled: disabled, className: utils.cn("w-full justify-start text-left font-normal", !dateValue && "text-muted-foreground", error && "border-destructive", className), children: [jsxRuntime.jsx(lucideReact.CalendarIcon, { className: "mr-2 h-4 w-4" }), dateValue ? formatDate(dateValue) : placeholder || "Pick a date"] }) }), jsxRuntime.jsx(popover.PopoverContent, { className: "w-auto p-0", align: "start", children: jsxRuntime.jsx(calendar.Calendar, { mode: "single", selected: dateValue, onSelect: (date) => onChange(date ? date.toISOString().split("T")[0] : ""), disabled: (date) => {
630
+ if (resolvedMinDate && date < resolvedMinDate)
631
+ return true;
632
+ if (resolvedMaxDate && date > resolvedMaxDate)
633
+ return true;
634
+ return false;
635
+ }, initialFocus: true }) })] }));
636
+ }
637
+ }
638
+
639
+ class Hidden extends BaseField {
640
+ fieldType = "hidden";
641
+ static make(name) {
642
+ return new Hidden(name);
643
+ }
644
+ renderField({ value }) {
645
+ return jsxRuntime.jsx("input", { type: "hidden", name: this.config.name, value: value ?? "" });
646
+ }
647
+ }
648
+
649
+ class FileUpload extends BaseField {
650
+ fieldType = "file-upload";
651
+ constructor(name) {
652
+ super(name);
653
+ this.config.multiple = false;
654
+ this.config.preview = true;
655
+ this.config.maxFiles = 1;
656
+ }
657
+ static make(name) {
658
+ return new FileUpload(name);
659
+ }
660
+ accept(accept) {
661
+ this.config.accept = accept;
662
+ return this;
663
+ }
664
+ maxSize(bytes) {
665
+ this.config.maxSize = bytes;
666
+ return this;
667
+ }
668
+ multiple(multiple = true) {
669
+ this.config.multiple = multiple;
670
+ return this;
671
+ }
672
+ maxFiles(max) {
673
+ this.config.maxFiles = max;
674
+ return this;
675
+ }
676
+ preview(preview = true) {
677
+ this.config.preview = preview;
678
+ return this;
679
+ }
680
+ image() {
681
+ return this.accept("image/*");
682
+ }
683
+ pdf() {
684
+ return this.accept("application/pdf");
685
+ }
686
+ renderField({ value, onChange, error, disabled, }) {
687
+ const cfg = this.config;
688
+ const inputRef = react.useRef(null);
689
+ const [dragOver, setDragOver] = react.useState(false);
690
+ const files = Array.isArray(value) ? value : value ? [value] : [];
691
+ const handleFiles = (fileList) => {
692
+ if (!fileList)
693
+ return;
694
+ const newFiles = Array.from(fileList);
695
+ if (cfg.maxSize) {
696
+ const oversized = newFiles.find((f) => f.size > cfg.maxSize);
697
+ if (oversized)
698
+ return;
699
+ }
700
+ if (cfg.multiple) {
701
+ const combined = [...files, ...newFiles].slice(0, cfg.maxFiles);
702
+ onChange(combined);
703
+ }
704
+ else {
705
+ onChange(newFiles[0] || null);
706
+ }
707
+ };
708
+ const removeFile = (index) => {
709
+ if (cfg.multiple) {
710
+ const updated = files.filter((_, i) => i !== index);
711
+ onChange(updated.length ? updated : null);
712
+ }
713
+ else {
714
+ onChange(null);
715
+ }
716
+ };
717
+ return (jsxRuntime.jsxs("div", { className: utils.cn("space-y-2", cfg.className), children: [jsxRuntime.jsxs("div", { className: utils.cn("flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-6 transition-colors", dragOver
718
+ ? "border-primary bg-primary/5"
719
+ : "border-muted-foreground/25", error && "border-destructive", disabled && "cursor-not-allowed opacity-50"), onDragOver: (e) => {
720
+ e.preventDefault();
721
+ if (!disabled)
722
+ setDragOver(true);
723
+ }, onDragLeave: () => setDragOver(false), onDrop: (e) => {
724
+ e.preventDefault();
725
+ setDragOver(false);
726
+ if (!disabled)
727
+ handleFiles(e.dataTransfer.files);
728
+ }, children: [jsxRuntime.jsx(lucideReact.Upload, { className: "mb-2 h-8 w-8 text-muted-foreground" }), jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: ["Drag & drop or", " ", jsxRuntime.jsx("button", { type: "button", className: "text-primary underline", onClick: () => inputRef.current?.click(), disabled: disabled, children: "browse" })] }), cfg.accept && (jsxRuntime.jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: ["Accepted: ", cfg.accept] })), jsxRuntime.jsx("input", { ref: inputRef, type: "file", accept: cfg.accept, multiple: cfg.multiple, onChange: (e) => handleFiles(e.target.files), className: "hidden", disabled: disabled })] }), files.length > 0 && (jsxRuntime.jsx("ul", { className: "space-y-1", children: files.map((file, index) => (jsxRuntime.jsxs("li", { className: "flex items-center justify-between rounded-md border px-3 py-2 text-sm", children: [jsxRuntime.jsxs("span", { className: "flex items-center gap-2 truncate", children: [jsxRuntime.jsx(lucideReact.File, { className: "h-4 w-4 text-muted-foreground" }), file.name] }), jsxRuntime.jsx(button.Button, { type: "button", variant: "ghost", size: "sm", className: "h-6 w-6 p-0", onClick: () => removeFile(index), disabled: disabled, children: jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" }) })] }, index))) }))] }));
729
+ }
730
+ }
731
+
732
+ class CheckboxGroup extends BaseField {
733
+ fieldType = "checkbox-group";
734
+ constructor(name) {
735
+ super(name);
736
+ this.config.options = [];
737
+ this.config.columns = 1;
738
+ }
739
+ static make(name) {
740
+ return new CheckboxGroup(name);
741
+ }
742
+ options(options) {
743
+ this.config.options = options;
744
+ return this;
745
+ }
746
+ columns(columns) {
747
+ this.config.columns = columns;
748
+ return this;
749
+ }
750
+ renderField({ value, onChange, error, disabled, }) {
751
+ const cfg = this.config;
752
+ const selectedValues = Array.isArray(value) ? value : [];
753
+ const gridColsClass = {
754
+ 1: "grid-cols-1",
755
+ 2: "grid-cols-2",
756
+ 3: "grid-cols-3",
757
+ 4: "grid-cols-4",
758
+ };
759
+ const handleToggle = (optionValue, checked) => {
760
+ if (checked) {
761
+ onChange([...selectedValues, optionValue]);
762
+ }
763
+ else {
764
+ onChange(selectedValues.filter((v) => v !== optionValue));
765
+ }
766
+ };
767
+ return (jsxRuntime.jsx("div", { className: utils.cn("grid gap-2", gridColsClass[cfg.columns || 1] || gridColsClass[1], cfg.className), children: cfg.options.map((opt) => (jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [jsxRuntime.jsx(checkbox.Checkbox, { id: `${cfg.name}-${opt.value}`, checked: selectedValues.includes(opt.value), onCheckedChange: (checked) => handleToggle(opt.value, !!checked), disabled: disabled || opt.disabled, className: utils.cn(error && "border-destructive") }), jsxRuntime.jsx(label.Label, { htmlFor: `${cfg.name}-${opt.value}`, className: "text-sm font-normal", children: opt.label })] }, opt.value))) }));
768
+ }
769
+ }
770
+
771
+ class Repeater extends BaseField {
772
+ fieldType = "repeater";
773
+ fieldBuilders = [];
774
+ constructor(name) {
775
+ super(name);
776
+ this.config.minItems = 0;
777
+ this.config.maxItems = Infinity;
778
+ this.config.addLabel = "Add item";
779
+ this.config.collapsible = false;
780
+ this.config.orderable = false;
781
+ }
782
+ static make(name) {
783
+ return new Repeater(name);
784
+ }
785
+ fields(...builders) {
786
+ this.fieldBuilders = builders;
787
+ this.config.fields = builders.map((b) => b.build());
788
+ return this;
789
+ }
790
+ minItems(min) {
791
+ this.config.minItems = min;
792
+ return this;
793
+ }
794
+ maxItems(max) {
795
+ this.config.maxItems = max;
796
+ return this;
797
+ }
798
+ addLabel(label) {
799
+ this.config.addLabel = label;
800
+ return this;
801
+ }
802
+ collapsible(collapsible = true) {
803
+ this.config.collapsible = collapsible;
804
+ return this;
805
+ }
806
+ orderable(orderable = true) {
807
+ this.config.orderable = orderable;
808
+ return this;
809
+ }
810
+ renderField({ value, onChange, error, disabled, data, }) {
811
+ const cfg = this.config;
812
+ const items = Array.isArray(value) ? value : [];
813
+ const builtFields = cfg.fields;
814
+ const addItem = () => {
815
+ if (items.length >= (cfg.maxItems || Infinity))
816
+ return;
817
+ const defaults = {};
818
+ builtFields.forEach((f) => {
819
+ defaults[f.name] = f.config.defaultValue ?? "";
820
+ });
821
+ onChange([...items, defaults]);
822
+ };
823
+ const removeItem = (index) => {
824
+ if (items.length <= (cfg.minItems || 0))
825
+ return;
826
+ onChange(items.filter((_, i) => i !== index));
827
+ };
828
+ const updateItem = (index, fieldName, fieldValue) => {
829
+ const updated = items.map((item, i) => i === index ? { ...item, [fieldName]: fieldValue } : item);
830
+ onChange(updated);
831
+ };
832
+ const canAdd = items.length < (cfg.maxItems || Infinity);
833
+ const canRemove = items.length > (cfg.minItems || 0);
834
+ return (jsxRuntime.jsxs("div", { className: utils.cn("space-y-3", cfg.className), children: [items.map((item, index) => (jsxRuntime.jsx(card.Card, { children: jsxRuntime.jsxs(card.CardContent, { className: "flex items-start gap-3 pt-4", children: [cfg.orderable && (jsxRuntime.jsx(lucideReact.GripVertical, { className: "mt-2 h-5 w-5 cursor-grab text-muted-foreground" })), jsxRuntime.jsx("div", { className: "grid flex-1 gap-3", children: builtFields.map((field) => (jsxRuntime.jsxs("div", { className: "space-y-1", children: [field.config.label && (jsxRuntime.jsx("label", { className: "text-sm font-medium", children: field.config.label })), field.render({
835
+ value: item[field.name],
836
+ onChange: (v) => updateItem(index, field.name, v),
837
+ disabled,
838
+ data,
839
+ })] }, field.name))) }), canRemove && (jsxRuntime.jsx(button.Button, { type: "button", variant: "ghost", size: "sm", className: "mt-1 h-8 w-8 p-0 text-destructive", onClick: () => removeItem(index), disabled: disabled, children: jsxRuntime.jsx(lucideReact.Trash2, { className: "h-4 w-4" }) }))] }) }, index))), canAdd && (jsxRuntime.jsxs(button.Button, { type: "button", variant: "outline", size: "sm", onClick: addItem, disabled: disabled, className: "w-full", children: [jsxRuntime.jsx(lucideReact.Plus, { className: "mr-2 h-4 w-4" }), cfg.addLabel] }))] }));
840
+ }
841
+ }
842
+
843
+ function FieldRenderer({ field, value, error, disabled, data, onChange, onBlur, }) {
844
+ // Hidden fields render without wrapper
845
+ if (field.type === "hidden") {
846
+ return field.render({ value, onChange, onBlur, error, disabled, data });
847
+ }
848
+ // Checkbox and Toggle handle their own labels inline
849
+ const skipLabel = field.type === "checkbox" || field.type === "toggle";
850
+ return (jsxRuntime.jsxs("div", { className: utils.cn("space-y-2", field.config.columnSpan && field.config.columnSpan > 1
851
+ ? `col-span-${field.config.columnSpan}`
852
+ : undefined, field.config.className), children: [field.config.label && !skipLabel && (jsxRuntime.jsxs(label.Label, { htmlFor: field.name, className: utils.cn(error && "text-destructive"), children: [field.config.label, field.config.required && (jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" }))] })), field.render({
853
+ value,
854
+ onChange,
855
+ onBlur,
856
+ error,
857
+ disabled,
858
+ data,
859
+ }), error && jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: error }), !error && field.config.helperText && (jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: field.config.helperText }))] }));
860
+ }
861
+
862
+ const gridColsClass = {
863
+ 1: "grid-cols-1",
864
+ 2: "grid-cols-1 sm:grid-cols-2",
865
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
866
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
867
+ };
868
+ function GridLayout({ columns = 1, children, className, }) {
869
+ return (jsxRuntime.jsx("div", { className: utils.cn("grid gap-4", gridColsClass[columns] || gridColsClass[1], className), children: children }));
870
+ }
871
+
872
+ const positionClass = {
873
+ start: "justify-start",
874
+ center: "justify-center",
875
+ between: "justify-between",
876
+ end: "justify-end",
877
+ };
878
+ function FormActions({ actions, position = "end", data, processing = false, }) {
879
+ if (!actions.length)
880
+ return null;
881
+ return (jsxRuntime.jsx("div", { className: utils.cn("flex gap-2", positionClass[position]), children: actions.map((action, i) => {
882
+ const isDisabled = typeof action.disabled === "function"
883
+ ? action.disabled(data, processing)
884
+ : action.disabled;
885
+ if (action.type === "submit") {
886
+ return (jsxRuntime.jsxs(button.Button, { type: "submit", variant: action.variant || "default", disabled: isDisabled || processing, children: [action.icon && jsxRuntime.jsx("span", { className: "mr-2", children: action.icon }), processing ? "Processing..." : action.label] }, i));
887
+ }
888
+ if (action.type === "cancel" && action.href) {
889
+ return (jsxRuntime.jsx(button.Button, { type: "button", variant: action.variant || "outline", disabled: processing, asChild: true, children: jsxRuntime.jsxs("a", { href: action.href, children: [action.icon && jsxRuntime.jsx("span", { className: "mr-2", children: action.icon }), action.label] }) }, i));
890
+ }
891
+ return (jsxRuntime.jsxs(button.Button, { type: "button", variant: action.variant || "outline", onClick: action.onClick, disabled: isDisabled || (action.type === "cancel" && processing), children: [action.icon && jsxRuntime.jsx("span", { className: "mr-2", children: action.icon }), action.label] }, i));
892
+ }) }));
893
+ }
894
+
895
+ function SectionRenderer({ section, fields, data, errors, onChange, onBlur, isFieldVisible, isFieldDisabled, }) {
896
+ const [isCollapsed, setIsCollapsed] = react.useState(section.collapsed ?? false);
897
+ if (section.hidden && section.hidden(data))
898
+ return null;
899
+ const sectionFields = fields.filter((f) => section.fields.includes(f.name));
900
+ return (jsxRuntime.jsxs(card.Card, { children: [jsxRuntime.jsxs(card.CardHeader, { className: utils.cn(section.collapsible && "cursor-pointer select-none"), onClick: section.collapsible ? () => setIsCollapsed(!isCollapsed) : undefined, children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [section.icon, jsxRuntime.jsx(card.CardTitle, { className: "text-lg", children: section.title })] }), section.collapsible && (jsxRuntime.jsx(button.Button, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", children: jsxRuntime.jsx(lucideReact.ChevronDown, { className: utils.cn("h-4 w-4 transition-transform", isCollapsed && "-rotate-90") }) }))] }), section.description && (jsxRuntime.jsx(card.CardDescription, { children: section.description }))] }), !isCollapsed && (jsxRuntime.jsx(card.CardContent, { children: jsxRuntime.jsx(GridLayout, { columns: section.columns, children: sectionFields.map((field) => {
901
+ if (!isFieldVisible(field))
902
+ return null;
903
+ return (jsxRuntime.jsx(FieldRenderer, { field: field, value: data[field.name], error: errors[field.name], disabled: isFieldDisabled(field), data: data, onChange: (v) => onChange(field.name, v), onBlur: onBlur ? () => onBlur(field.name) : undefined }, field.name));
904
+ }) }) }))] }));
905
+ }
906
+
907
+ function TabRenderer({ tabs: tabs$1, fields, data, errors, onChange, onBlur, isFieldVisible, isFieldDisabled, columns, }) {
908
+ const firstTab = tabs$1[0]?.id;
909
+ return (jsxRuntime.jsxs(tabs.Tabs, { defaultValue: firstTab, children: [jsxRuntime.jsx(tabs.TabsList, { children: tabs$1.map((tab) => {
910
+ const isDisabled = tab.disabled ? tab.disabled(data) : false;
911
+ const badge = typeof tab.badge === "function" ? tab.badge(data) : tab.badge;
912
+ return (jsxRuntime.jsx(tabs.TabsTrigger, { value: tab.id, disabled: isDisabled, children: jsxRuntime.jsxs("span", { className: "flex items-center gap-2", children: [tab.icon, tab.label, badge !== undefined && badge !== null && (jsxRuntime.jsx("span", { className: "ml-1 rounded-full bg-muted px-2 py-0.5 text-xs", children: badge }))] }) }, tab.id));
913
+ }) }), tabs$1.map((tab) => {
914
+ const tabFields = tab.fields
915
+ ? fields.filter((f) => tab.fields.includes(f.name))
916
+ : [];
917
+ return (jsxRuntime.jsx(tabs.TabsContent, { value: tab.id, className: "mt-4", children: tab.sections ? (jsxRuntime.jsx("div", { className: "space-y-4", children: tab.sections.map((section) => (jsxRuntime.jsx(SectionRenderer, { section: section, fields: fields, data: data, errors: errors, onChange: onChange, onBlur: onBlur, isFieldVisible: isFieldVisible, isFieldDisabled: isFieldDisabled }, section.id))) })) : (jsxRuntime.jsx(GridLayout, { columns: columns, children: tabFields.map((field) => {
918
+ if (!isFieldVisible(field))
919
+ return null;
920
+ return (jsxRuntime.jsx(FieldRenderer, { field: field, value: data[field.name], error: errors[field.name], disabled: isFieldDisabled(field), data: data, onChange: (v) => onChange(field.name, v), onBlur: onBlur ? () => onBlur(field.name) : undefined }, field.name));
921
+ }) })) }, tab.id));
922
+ })] }));
923
+ }
924
+
925
+ function WizardRenderer({ steps, fields, data, errors, onChange, onBlur, isFieldVisible, isFieldDisabled, columns, onSubmit, processing = false, }) {
926
+ const [currentStep, setCurrentStep] = react.useState(0);
927
+ const currentStepConfig = steps[currentStep];
928
+ const isLastStep = currentStep === steps.length - 1;
929
+ const isFirstStep = currentStep === 0;
930
+ const canProceed = currentStepConfig?.canProceed
931
+ ? currentStepConfig.canProceed(data)
932
+ : true;
933
+ const handleNext = react.useCallback(async () => {
934
+ if (currentStepConfig?.beforeNext) {
935
+ const canContinue = await currentStepConfig.beforeNext(data);
936
+ if (!canContinue)
937
+ return;
938
+ }
939
+ if (isLastStep) {
940
+ onSubmit();
941
+ }
942
+ else {
943
+ setCurrentStep((prev) => Math.min(prev + 1, steps.length - 1));
944
+ }
945
+ }, [currentStep, currentStepConfig, data, isLastStep, onSubmit, steps.length]);
946
+ const handlePrevious = react.useCallback(() => {
947
+ setCurrentStep((prev) => Math.max(prev - 1, 0));
948
+ }, []);
949
+ const stepFields = currentStepConfig?.fields
950
+ ? fields.filter((f) => currentStepConfig.fields.includes(f.name))
951
+ : [];
952
+ return (jsxRuntime.jsxs("div", { className: "space-y-6", children: [jsxRuntime.jsx("nav", { "aria-label": "Progress", children: jsxRuntime.jsx("ol", { className: "flex items-center", children: steps.map((step, index) => (jsxRuntime.jsxs("li", { className: utils.cn("flex items-center", index < steps.length - 1 && "flex-1"), children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("div", { className: utils.cn("flex h-8 w-8 items-center justify-center rounded-full border-2 text-sm font-medium", index < currentStep &&
953
+ "border-primary bg-primary text-primary-foreground", index === currentStep &&
954
+ "border-primary text-primary", index > currentStep &&
955
+ "border-muted-foreground/25 text-muted-foreground"), children: index < currentStep ? (jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4" })) : (index + 1) }), jsxRuntime.jsxs("div", { className: "hidden sm:block", children: [jsxRuntime.jsx("p", { className: utils.cn("text-sm font-medium", index <= currentStep
956
+ ? "text-foreground"
957
+ : "text-muted-foreground"), children: step.label }), step.description && (jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: step.description }))] })] }), index < steps.length - 1 && (jsxRuntime.jsx("div", { className: utils.cn("mx-4 hidden h-0.5 flex-1 sm:block", index < currentStep ? "bg-primary" : "bg-muted") }))] }, step.id))) }) }), jsxRuntime.jsx("div", { children: currentStepConfig?.sections ? (jsxRuntime.jsx("div", { className: "space-y-4", children: currentStepConfig.sections.map((section) => (jsxRuntime.jsx(SectionRenderer, { section: section, fields: fields, data: data, errors: errors, onChange: onChange, onBlur: onBlur, isFieldVisible: isFieldVisible, isFieldDisabled: isFieldDisabled }, section.id))) })) : (jsxRuntime.jsx(GridLayout, { columns: columns, children: stepFields.map((field) => {
958
+ if (!isFieldVisible(field))
959
+ return null;
960
+ return (jsxRuntime.jsx(FieldRenderer, { field: field, value: data[field.name], error: errors[field.name], disabled: isFieldDisabled(field), data: data, onChange: (v) => onChange(field.name, v), onBlur: onBlur ? () => onBlur(field.name) : undefined }, field.name));
961
+ }) })) }), jsxRuntime.jsxs("div", { className: "flex justify-between", children: [jsxRuntime.jsx(button.Button, { type: "button", variant: "outline", onClick: handlePrevious, disabled: isFirstStep, children: "Previous" }), jsxRuntime.jsx(button.Button, { type: isLastStep ? "submit" : "button", onClick: handleNext, disabled: !canProceed || (isLastStep && processing), children: isLastStep
962
+ ? processing
963
+ ? "Processing..."
964
+ : "Submit"
965
+ : "Next" })] })] }));
966
+ }
967
+
968
+ function FormRenderer({ schema, data, errors, onChange, onSubmit, processing = false, className, disabled = false, onBlur, }) {
969
+ const { fields, config } = schema;
970
+ const resolvedTitle = react.useMemo(() => {
971
+ if (typeof config.title === "function")
972
+ return config.title(data);
973
+ return config.title;
974
+ }, [config.title, data]);
975
+ const resolvedDescription = react.useMemo(() => {
976
+ if (typeof config.description === "function")
977
+ return config.description(data);
978
+ return config.description;
979
+ }, [config.description, data]);
980
+ const isFieldVisible = react.useCallback((field) => {
981
+ if (typeof field.config.hidden === "function")
982
+ return !field.config.hidden(data);
983
+ if (typeof field.config.hidden === "boolean")
984
+ return !field.config.hidden;
985
+ for (const dep of field.config.dependsOn || []) {
986
+ const depValue = data[dep.field];
987
+ if (dep.effect === "show" && !dep.condition(depValue, data))
988
+ return false;
989
+ if (dep.effect === "hide" && dep.condition(depValue, data))
990
+ return false;
991
+ }
992
+ return true;
993
+ }, [data]);
994
+ const isFieldDisabled = react.useCallback((field) => {
995
+ if (disabled)
996
+ return true;
997
+ if (typeof config.disabled === "function" && config.disabled(data))
998
+ return true;
999
+ if (typeof config.disabled === "boolean" && config.disabled)
1000
+ return true;
1001
+ if (typeof field.config.disabled === "function")
1002
+ return field.config.disabled(data);
1003
+ if (typeof field.config.disabled === "boolean")
1004
+ return field.config.disabled;
1005
+ for (const dep of field.config.dependsOn || []) {
1006
+ const depValue = data[dep.field];
1007
+ if (dep.effect === "disable" && dep.condition(depValue, data))
1008
+ return true;
1009
+ if (dep.effect === "enable" &&
1010
+ !dep.condition(depValue, data))
1011
+ return true;
1012
+ }
1013
+ return false;
1014
+ }, [disabled, config.disabled, data]);
1015
+ const renderFieldsFlat = () => (jsxRuntime.jsx(GridLayout, { columns: config.columns, children: fields.map((field) => {
1016
+ if (!isFieldVisible(field))
1017
+ return null;
1018
+ return (jsxRuntime.jsx(FieldRenderer, { field: field, value: data[field.name], error: errors[field.name], disabled: isFieldDisabled(field), data: data, onChange: (v) => onChange(field.name, v), onBlur: onBlur ? () => onBlur(field.name) : undefined }, field.name));
1019
+ }) }));
1020
+ const renderContent = () => {
1021
+ // Wizard mode
1022
+ if (config.wizardSteps?.length) {
1023
+ return (jsxRuntime.jsx(WizardRenderer, { steps: config.wizardSteps, fields: fields, data: data, errors: errors, onChange: onChange, onBlur: onBlur, isFieldVisible: isFieldVisible, isFieldDisabled: isFieldDisabled, columns: config.columns, onSubmit: onSubmit, processing: processing }));
1024
+ }
1025
+ // Tabs mode
1026
+ if (config.tabs?.length) {
1027
+ return (jsxRuntime.jsx(TabRenderer, { tabs: config.tabs, fields: fields, data: data, errors: errors, onChange: onChange, onBlur: onBlur, isFieldVisible: isFieldVisible, isFieldDisabled: isFieldDisabled, columns: config.columns }));
1028
+ }
1029
+ // Sections mode
1030
+ if (config.sections?.length) {
1031
+ return (jsxRuntime.jsx("div", { className: "space-y-4", children: config.sections.map((section) => (jsxRuntime.jsx(SectionRenderer, { section: section, fields: fields, data: data, errors: errors, onChange: onChange, onBlur: onBlur, isFieldVisible: isFieldVisible, isFieldDisabled: isFieldDisabled }, section.id))) }));
1032
+ }
1033
+ // Flat mode (default)
1034
+ return renderFieldsFlat();
1035
+ };
1036
+ const spacingClass = {
1037
+ compact: "space-y-3",
1038
+ normal: "space-y-6",
1039
+ relaxed: "space-y-8",
1040
+ }[config.spacing || "normal"];
1041
+ // Wizard handles its own submit button
1042
+ const showActions = config.actions?.length && !config.wizardSteps?.length;
1043
+ const formBody = (jsxRuntime.jsxs("form", { onSubmit: (e) => {
1044
+ e.preventDefault();
1045
+ onSubmit();
1046
+ }, className: utils.cn(spacingClass, className), children: [(resolvedTitle || resolvedDescription) && (jsxRuntime.jsxs("div", { className: "space-y-1", children: [resolvedTitle && (jsxRuntime.jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: resolvedTitle })), resolvedDescription && (jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: resolvedDescription }))] })), renderContent(), showActions && (jsxRuntime.jsx(FormActions, { actions: config.actions, position: config.actionsPosition, data: data, processing: processing }))] }));
1047
+ if (config.bordered) {
1048
+ return (jsxRuntime.jsx(card.Card, { children: jsxRuntime.jsx(card.CardContent, { className: "pt-6", children: formBody }) }));
1049
+ }
1050
+ return formBody;
1051
+ }
1052
+
1053
+ exports.ActionsBuilder = ActionsBuilder;
1054
+ exports.BaseField = BaseField;
1055
+ exports.Checkbox = Checkbox;
1056
+ exports.CheckboxGroup = CheckboxGroup;
1057
+ exports.DatePicker = DatePicker;
1058
+ exports.FieldRenderer = FieldRenderer;
1059
+ exports.FileUpload = FileUpload;
1060
+ exports.FormActions = FormActions;
1061
+ exports.FormRenderer = FormRenderer;
1062
+ exports.FormSchema = FormSchema;
1063
+ exports.GridLayout = GridLayout;
1064
+ exports.Hidden = Hidden;
1065
+ exports.RadioGroup = RadioGroup;
1066
+ exports.Repeater = Repeater;
1067
+ exports.SectionBuilder = SectionBuilder;
1068
+ exports.SectionRenderer = SectionRenderer;
1069
+ exports.Select = Select;
1070
+ exports.TabBuilder = TabBuilder;
1071
+ exports.TabRenderer = TabRenderer;
1072
+ exports.TextInput = TextInput;
1073
+ exports.Textarea = Textarea;
1074
+ exports.Toggle = Toggle;
1075
+ exports.WizardRenderer = WizardRenderer;
1076
+ exports.WizardStep = WizardStep;
1077
+ //# sourceMappingURL=index.js.map