@mehdashti/forms 0.1.0 → 0.2.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.
- package/README.md +100 -0
- package/dist/index.js +105 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,9 @@ Built on React Hook Form + Zod with smart defaults and seamless integration with
|
|
|
10
10
|
- ✅ **Real-time Validation** - Validate on change by default
|
|
11
11
|
- ✅ **Smart Defaults** - Sensible defaults based on APISmith patterns
|
|
12
12
|
- ✅ **Form Field Components** - Pre-built field components with error display
|
|
13
|
+
- ✅ **Layout Components** - Ready-to-use 1, 2, 3, 4 column layouts (NEW!)
|
|
14
|
+
- ✅ **Form Sections** - Organize forms with titles and descriptions (NEW!)
|
|
15
|
+
- ✅ **Advanced Grids** - Custom column spans with FormGrid (NEW!)
|
|
13
16
|
- ✅ **Field Arrays** - Dynamic form fields support
|
|
14
17
|
- ✅ **TypeScript First** - Full type safety with excellent IntelliSense
|
|
15
18
|
- ✅ **@mehdashti/ui Integration** - Works seamlessly with platform UI components
|
|
@@ -277,6 +280,103 @@ function RegistrationForm() {
|
|
|
277
280
|
}
|
|
278
281
|
```
|
|
279
282
|
|
|
283
|
+
## Form Layouts
|
|
284
|
+
|
|
285
|
+
Pre-built layout components for quick form creation.
|
|
286
|
+
|
|
287
|
+
### 1-Column Layout
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { useSmartForm, FormField, FormLayout, z } from '@mehdashti/forms'
|
|
291
|
+
|
|
292
|
+
const form = useSmartForm({ schema, onSubmit: async (data) => {} })
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
<form onSubmit={form.handleSubmit}>
|
|
296
|
+
<FormLayout columns={1}>
|
|
297
|
+
<FormField name="email" label="Email" required control={form.control} />
|
|
298
|
+
<FormField name="password" label="Password" type="password" required control={form.control} />
|
|
299
|
+
</FormLayout>
|
|
300
|
+
</form>
|
|
301
|
+
)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### 2-Column Layout
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
import { FormLayout } from '@mehdashti/forms'
|
|
308
|
+
|
|
309
|
+
<FormLayout columns={2}>
|
|
310
|
+
<FormField name="firstName" label="First Name" required control={form.control} />
|
|
311
|
+
<FormField name="lastName" label="Last Name" required control={form.control} />
|
|
312
|
+
<FormField name="email" label="Email" required control={form.control} />
|
|
313
|
+
<FormField name="phone" label="Phone" required control={form.control} />
|
|
314
|
+
</FormLayout>
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 3-Column Layout
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
<FormLayout columns={3}>
|
|
321
|
+
<FormField name="name" label="Connection Name" required control={form.control} />
|
|
322
|
+
<FormSelect name="type" label="Type" required control={form.control} options={types} />
|
|
323
|
+
<FormField name="host" label="Host" required control={form.control} />
|
|
324
|
+
<FormField name="port" label="Port" type="number" required control={form.control} />
|
|
325
|
+
<FormField name="database" label="Database" required control={form.control} />
|
|
326
|
+
<FormField name="username" label="Username" required control={form.control} />
|
|
327
|
+
</FormLayout>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Form Sections
|
|
331
|
+
|
|
332
|
+
Organize forms into sections with titles:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import { FormSection } from '@mehdashti/forms'
|
|
336
|
+
|
|
337
|
+
<div className="space-y-8">
|
|
338
|
+
<FormSection title="Personal Information" description="Enter your details" columns={2}>
|
|
339
|
+
<FormField name="firstName" label="First Name" required control={form.control} />
|
|
340
|
+
<FormField name="lastName" label="Last Name" required control={form.control} />
|
|
341
|
+
</FormSection>
|
|
342
|
+
|
|
343
|
+
<FormSection title="Company Information" columns={2}>
|
|
344
|
+
<FormField name="company" label="Company" required control={form.control} />
|
|
345
|
+
<FormField name="position" label="Position" required control={form.control} />
|
|
346
|
+
</FormSection>
|
|
347
|
+
</div>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Advanced Grid Layouts
|
|
351
|
+
|
|
352
|
+
Use `FormGrid` and `FormGridItem` for custom column spans:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
import { FormGrid, FormGridItem } from '@mehdashti/forms'
|
|
356
|
+
|
|
357
|
+
<FormGrid>
|
|
358
|
+
{/* Full width */}
|
|
359
|
+
<FormGridItem colSpan="full">
|
|
360
|
+
<FormField name="title" label="Title" required control={form.control} />
|
|
361
|
+
</FormGridItem>
|
|
362
|
+
|
|
363
|
+
{/* 2 columns */}
|
|
364
|
+
<FormGridItem colSpan={1}>
|
|
365
|
+
<FormField name="firstName" label="First Name" required control={form.control} />
|
|
366
|
+
</FormGridItem>
|
|
367
|
+
<FormGridItem colSpan={1}>
|
|
368
|
+
<FormField name="lastName" label="Last Name" required control={form.control} />
|
|
369
|
+
</FormGridItem>
|
|
370
|
+
|
|
371
|
+
{/* Full width */}
|
|
372
|
+
<FormGridItem colSpan="full">
|
|
373
|
+
<FormField name="bio" label="Bio" control={form.control} />
|
|
374
|
+
</FormGridItem>
|
|
375
|
+
</FormGrid>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**See [LAYOUT_EXAMPLES.md](./LAYOUT_EXAMPLES.md) for complete examples.**
|
|
379
|
+
|
|
280
380
|
## API Reference
|
|
281
381
|
|
|
282
382
|
### `useSmartForm(options)`
|
package/dist/index.js
CHANGED
|
@@ -188,6 +188,110 @@ function FormCheckbox({
|
|
|
188
188
|
}
|
|
189
189
|
);
|
|
190
190
|
}
|
|
191
|
+
var spacingClasses = {
|
|
192
|
+
sm: "gap-3",
|
|
193
|
+
md: "gap-4",
|
|
194
|
+
lg: "gap-6"
|
|
195
|
+
};
|
|
196
|
+
var columnClasses = {
|
|
197
|
+
responsive: {
|
|
198
|
+
1: "grid-cols-1",
|
|
199
|
+
2: "grid-cols-1 sm:grid-cols-2",
|
|
200
|
+
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
|
201
|
+
4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4"
|
|
202
|
+
},
|
|
203
|
+
fixed: {
|
|
204
|
+
1: "grid-cols-1",
|
|
205
|
+
2: "grid-cols-2",
|
|
206
|
+
3: "grid-cols-3",
|
|
207
|
+
4: "grid-cols-4"
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
function FormLayout({
|
|
211
|
+
columns = 1,
|
|
212
|
+
spacing = "md",
|
|
213
|
+
responsive = true,
|
|
214
|
+
className = "",
|
|
215
|
+
children,
|
|
216
|
+
...props
|
|
217
|
+
}) {
|
|
218
|
+
const gridClasses = responsive ? columnClasses.responsive[columns] : columnClasses.fixed[columns];
|
|
219
|
+
return /* @__PURE__ */ jsx(
|
|
220
|
+
"div",
|
|
221
|
+
{
|
|
222
|
+
className: `grid ${gridClasses} ${spacingClasses[spacing]} ${className}`,
|
|
223
|
+
...props,
|
|
224
|
+
children
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
FormLayout.displayName = "FormLayout";
|
|
229
|
+
var spacingClasses2 = {
|
|
230
|
+
sm: "gap-3",
|
|
231
|
+
md: "gap-4",
|
|
232
|
+
lg: "gap-6"
|
|
233
|
+
};
|
|
234
|
+
var columnClasses2 = {
|
|
235
|
+
1: "grid-cols-1",
|
|
236
|
+
2: "grid-cols-1 sm:grid-cols-2",
|
|
237
|
+
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
|
238
|
+
4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4"
|
|
239
|
+
};
|
|
240
|
+
function FormSection({
|
|
241
|
+
title,
|
|
242
|
+
description,
|
|
243
|
+
columns = 1,
|
|
244
|
+
spacing = "md",
|
|
245
|
+
className = "",
|
|
246
|
+
children,
|
|
247
|
+
...props
|
|
248
|
+
}) {
|
|
249
|
+
return /* @__PURE__ */ jsxs("div", { className: `space-y-4 ${className}`, ...props, children: [
|
|
250
|
+
(title || description) && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
251
|
+
title && /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold leading-none tracking-tight", children: title }),
|
|
252
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
|
|
253
|
+
] }),
|
|
254
|
+
/* @__PURE__ */ jsx("div", { className: `grid ${columnClasses2[columns]} ${spacingClasses2[spacing]}`, children })
|
|
255
|
+
] });
|
|
256
|
+
}
|
|
257
|
+
FormSection.displayName = "FormSection";
|
|
258
|
+
var spacingClasses3 = {
|
|
259
|
+
sm: "gap-3",
|
|
260
|
+
md: "gap-4",
|
|
261
|
+
lg: "gap-6"
|
|
262
|
+
};
|
|
263
|
+
var colSpanClasses = {
|
|
264
|
+
1: "col-span-1",
|
|
265
|
+
2: "col-span-1 sm:col-span-2",
|
|
266
|
+
3: "col-span-1 sm:col-span-2 lg:col-span-3",
|
|
267
|
+
4: "col-span-1 sm:col-span-2 lg:col-span-4",
|
|
268
|
+
full: "col-span-full"
|
|
269
|
+
};
|
|
270
|
+
function FormGrid({
|
|
271
|
+
spacing = "md",
|
|
272
|
+
className = "",
|
|
273
|
+
children,
|
|
274
|
+
...props
|
|
275
|
+
}) {
|
|
276
|
+
return /* @__PURE__ */ jsx(
|
|
277
|
+
"div",
|
|
278
|
+
{
|
|
279
|
+
className: `grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 ${spacingClasses3[spacing]} ${className}`,
|
|
280
|
+
...props,
|
|
281
|
+
children
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
FormGrid.displayName = "FormGrid";
|
|
286
|
+
function FormGridItem({
|
|
287
|
+
colSpan = 1,
|
|
288
|
+
className = "",
|
|
289
|
+
children,
|
|
290
|
+
...props
|
|
291
|
+
}) {
|
|
292
|
+
return /* @__PURE__ */ jsx("div", { className: `${colSpanClasses[colSpan]} ${className}`, ...props, children });
|
|
293
|
+
}
|
|
294
|
+
FormGridItem.displayName = "FormGridItem";
|
|
191
295
|
function useSmartFieldArray({
|
|
192
296
|
name,
|
|
193
297
|
control,
|
|
@@ -207,6 +311,6 @@ function useSmartFieldArray({
|
|
|
207
311
|
};
|
|
208
312
|
}
|
|
209
313
|
|
|
210
|
-
export { FormCheckbox, FormField, FormSelect, useSmartFieldArray, useSmartForm };
|
|
314
|
+
export { FormCheckbox, FormField, FormGrid, FormGridItem, FormLayout, FormSection, FormSelect, useSmartFieldArray, useSmartForm };
|
|
211
315
|
//# sourceMappingURL=index.js.map
|
|
212
316
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/use-smart-form.ts","../src/form-field.tsx","../src/form-select.tsx","../src/form-checkbox.tsx","../src/use-field-array.ts"],"names":["errors","jsx","Controller","jsxs","rhfUseFieldArray"],"mappings":"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","file":"index.js","sourcesContent":["import { useForm } from 'react-hook-form'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport type { FieldValues, Path, UseFormReturn } from 'react-hook-form'\nimport type { z } from 'zod'\n\nexport interface SmartFormOptions<TFieldValues extends FieldValues = FieldValues> {\n schema: z.ZodSchema<TFieldValues>\n onSubmit: (data: TFieldValues) => void | Promise<void>\n onError?: (errors: Record<string, unknown>) => void\n realtimeValidation?: boolean\n defaultValues?: Partial<TFieldValues>\n mode?: 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all'\n}\n\n/**\n * Enhanced React Hook Form with Zod validation and smart defaults\n */\nexport function useSmartForm<TFieldValues extends FieldValues = FieldValues>(\n options: SmartFormOptions<TFieldValues>\n) {\n const { schema, onSubmit, onError, realtimeValidation = true, ...formOptions } = options\n\n const form = useForm<TFieldValues>({\n resolver: zodResolver(schema),\n mode: realtimeValidation ? 'onChange' : (formOptions.mode || 'onSubmit'),\n ...formOptions,\n })\n\n const {\n handleSubmit: rhfHandleSubmit,\n formState: { isSubmitting, errors },\n } = form\n\n const hasErrors = Object.keys(errors).length > 0\n\n const getError = (name: Path<TFieldValues>): string | undefined => {\n const error = errors[name]\n return error?.message as string | undefined\n }\n\n const handleSubmit = rhfHandleSubmit(\n async (data) => {\n try {\n await onSubmit(data)\n } catch (error) {\n if (onError) {\n onError(error as Record<string, unknown>)\n } else {\n console.error('Form submission error:', error)\n }\n }\n },\n (errors) => {\n if (onError) {\n onError(errors)\n }\n }\n )\n\n return {\n ...form,\n handleSubmit,\n isSubmitting,\n hasErrors,\n getError,\n }\n}\n\nexport type SmartFormReturn<TFieldValues extends FieldValues = FieldValues> = ReturnType<typeof useSmartForm<TFieldValues>>\n","import { Controller } from 'react-hook-form'\nimport type { FieldValues } from 'react-hook-form'\nimport type { FormFieldProps } from './form-types'\n\n/**\n * Smart Form Field component with automatic error handling\n *\n * @example\n * ```tsx\n * <FormField\n * name=\"email\"\n * label=\"Email\"\n * type=\"email\"\n * required\n * control={form.control}\n * placeholder=\"Enter your email\"\n * />\n * ```\n */\nexport function FormField<TFieldValues extends FieldValues = FieldValues>({\n name,\n label,\n type = 'text',\n placeholder,\n required = false,\n helpText,\n disabled = false,\n className,\n control,\n render,\n}: FormFieldProps<TFieldValues>) {\n return (\n <Controller\n name={name}\n control={control}\n render={({ field, fieldState: { error } }) => (\n <div className={`space-y-2 ${className || ''}`}>\n <label htmlFor={String(name)} className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n\n {render ? (\n render(field)\n ) : (\n <input\n id={String(name)}\n type={type}\n placeholder={placeholder}\n disabled={disabled}\n className={`flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${\n error ? 'border-destructive' : ''\n }`}\n aria-invalid={!!error}\n {...field}\n value={field.value || ''}\n />\n )}\n\n {error && (\n <p className=\"text-sm text-destructive\">{error.message}</p>\n )}\n\n {helpText && !error && (\n <p className=\"text-xs text-muted-foreground\">{helpText}</p>\n )}\n </div>\n )}\n />\n )\n}\n","import { Controller } from 'react-hook-form'\nimport type { FieldValues } from 'react-hook-form'\nimport type { FormSelectProps } from './form-types'\n\n/**\n * Smart Form Select component\n *\n * @example\n * ```tsx\n * <FormSelect\n * name=\"country\"\n * label=\"Country\"\n * required\n * control={form.control}\n * options={[\n * { value: 'us', label: 'United States' },\n * { value: 'uk', label: 'United Kingdom' },\n * ]}\n * />\n * ```\n */\nexport function FormSelect<TFieldValues extends FieldValues = FieldValues>({\n name,\n label,\n options,\n placeholder,\n required = false,\n helpText,\n disabled = false,\n className,\n control,\n}: FormSelectProps<TFieldValues>) {\n return (\n <Controller\n name={name}\n control={control}\n render={({ field, fieldState: { error } }) => (\n <div className={`space-y-2 ${className || ''}`}>\n <label htmlFor={String(name)} className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n\n <select\n id={String(name)}\n disabled={disabled}\n className={`flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${\n error ? 'border-destructive' : ''\n }`}\n aria-invalid={!!error}\n {...field}\n value={field.value || ''}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map((option) => (\n <option\n key={String(option.value)}\n value={option.value}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </select>\n\n {error && (\n <p className=\"text-sm text-destructive\">{error.message}</p>\n )}\n\n {helpText && !error && (\n <p className=\"text-xs text-muted-foreground\">{helpText}</p>\n )}\n </div>\n )}\n />\n )\n}\n","import { Controller } from 'react-hook-form'\nimport type { FieldValues } from 'react-hook-form'\nimport type { FormCheckboxProps } from './form-types'\n\n/**\n * Smart Form Checkbox component\n *\n * @example\n * ```tsx\n * <FormCheckbox\n * name=\"acceptTerms\"\n * label=\"I accept the terms and conditions\"\n * required\n * control={form.control}\n * description=\"You must accept the terms to continue\"\n * />\n * ```\n */\nexport function FormCheckbox<TFieldValues extends FieldValues = FieldValues>({\n name,\n label,\n description,\n required = false,\n helpText,\n disabled = false,\n className,\n control,\n}: FormCheckboxProps<TFieldValues>) {\n return (\n <Controller\n name={name}\n control={control}\n render={({ field, fieldState: { error } }) => (\n <div className={`space-y-2 ${className || ''}`}>\n <div className=\"flex items-start space-x-3\">\n <input\n id={String(name)}\n type=\"checkbox\"\n disabled={disabled}\n className={`h-4 w-4 rounded border-input ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${\n error ? 'border-destructive' : ''\n }`}\n aria-invalid={!!error}\n checked={field.value || false}\n onChange={(e) => field.onChange(e.target.checked)}\n onBlur={field.onBlur}\n />\n <div className=\"flex-1 space-y-1 leading-none\">\n <label\n htmlFor={String(name)}\n className=\"text-sm font-medium cursor-pointer peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n </div>\n </div>\n\n {error && (\n <p className=\"text-sm text-destructive\">{error.message}</p>\n )}\n\n {helpText && !error && (\n <p className=\"text-xs text-muted-foreground\">{helpText}</p>\n )}\n </div>\n )}\n />\n )\n}\n","import { useFieldArray as rhfUseFieldArray } from 'react-hook-form'\nimport type { FieldValues, ArrayPath } from 'react-hook-form'\nimport type { UseFormReturn } from 'react-hook-form'\n\n/**\n * Field array options\n */\nexport interface FieldArrayOptions<TFieldValues extends FieldValues = FieldValues> {\n /**\n * Field array name\n */\n name: ArrayPath<TFieldValues>\n\n /**\n * Form control instance\n */\n control: UseFormReturn<TFieldValues>['control']\n\n /**\n * Default value for new items\n */\n defaultValue?: unknown\n}\n\n/**\n * Wrapper around React Hook Form's useFieldArray with smart defaults\n *\n * @example\n * ```tsx\n * const { fields, append, remove } = useSmartFieldArray({\n * name: 'items',\n * control: form.control,\n * defaultValue: { name: '', quantity: 0 }\n * })\n * ```\n */\nexport function useSmartFieldArray<TFieldValues extends FieldValues = FieldValues>({\n name,\n control,\n defaultValue,\n}: FieldArrayOptions<TFieldValues>) {\n const fieldArray = rhfUseFieldArray({\n name,\n control,\n })\n\n const { append: rhfAppend, ...rest } = fieldArray\n\n // Enhanced append with default value\n const append = (value?: unknown) => {\n rhfAppend((value || defaultValue) as never)\n }\n\n return {\n ...rest,\n append,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/use-smart-form.ts","../src/form-field.tsx","../src/form-select.tsx","../src/form-checkbox.tsx","../src/form-layout.tsx","../src/form-section.tsx","../src/form-grid.tsx","../src/use-field-array.ts"],"names":["errors","jsx","Controller","jsxs","spacingClasses","columnClasses","rhfUseFieldArray"],"mappings":"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","file":"index.js","sourcesContent":["import { useForm } from 'react-hook-form'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport type { FieldValues, Path, UseFormReturn } from 'react-hook-form'\nimport type { z } from 'zod'\n\nexport interface SmartFormOptions<TFieldValues extends FieldValues = FieldValues> {\n schema: z.ZodSchema<TFieldValues>\n onSubmit: (data: TFieldValues) => void | Promise<void>\n onError?: (errors: Record<string, unknown>) => void\n realtimeValidation?: boolean\n defaultValues?: Partial<TFieldValues>\n mode?: 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all'\n}\n\n/**\n * Enhanced React Hook Form with Zod validation and smart defaults\n */\nexport function useSmartForm<TFieldValues extends FieldValues = FieldValues>(\n options: SmartFormOptions<TFieldValues>\n) {\n const { schema, onSubmit, onError, realtimeValidation = true, ...formOptions } = options\n\n const form = useForm<TFieldValues>({\n resolver: zodResolver(schema),\n mode: realtimeValidation ? 'onChange' : (formOptions.mode || 'onSubmit'),\n ...formOptions,\n })\n\n const {\n handleSubmit: rhfHandleSubmit,\n formState: { isSubmitting, errors },\n } = form\n\n const hasErrors = Object.keys(errors).length > 0\n\n const getError = (name: Path<TFieldValues>): string | undefined => {\n const error = errors[name]\n return error?.message as string | undefined\n }\n\n const handleSubmit = rhfHandleSubmit(\n async (data) => {\n try {\n await onSubmit(data)\n } catch (error) {\n if (onError) {\n onError(error as Record<string, unknown>)\n } else {\n console.error('Form submission error:', error)\n }\n }\n },\n (errors) => {\n if (onError) {\n onError(errors)\n }\n }\n )\n\n return {\n ...form,\n handleSubmit,\n isSubmitting,\n hasErrors,\n getError,\n }\n}\n\nexport type SmartFormReturn<TFieldValues extends FieldValues = FieldValues> = ReturnType<typeof useSmartForm<TFieldValues>>\n","import { Controller } from 'react-hook-form'\nimport type { FieldValues } from 'react-hook-form'\nimport type { FormFieldProps } from './form-types'\n\n/**\n * Smart Form Field component with automatic error handling\n *\n * @example\n * ```tsx\n * <FormField\n * name=\"email\"\n * label=\"Email\"\n * type=\"email\"\n * required\n * control={form.control}\n * placeholder=\"Enter your email\"\n * />\n * ```\n */\nexport function FormField<TFieldValues extends FieldValues = FieldValues>({\n name,\n label,\n type = 'text',\n placeholder,\n required = false,\n helpText,\n disabled = false,\n className,\n control,\n render,\n}: FormFieldProps<TFieldValues>) {\n return (\n <Controller\n name={name}\n control={control}\n render={({ field, fieldState: { error } }) => (\n <div className={`space-y-2 ${className || ''}`}>\n <label htmlFor={String(name)} className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n\n {render ? (\n render(field)\n ) : (\n <input\n id={String(name)}\n type={type}\n placeholder={placeholder}\n disabled={disabled}\n className={`flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${\n error ? 'border-destructive' : ''\n }`}\n aria-invalid={!!error}\n {...field}\n value={field.value || ''}\n />\n )}\n\n {error && (\n <p className=\"text-sm text-destructive\">{error.message}</p>\n )}\n\n {helpText && !error && (\n <p className=\"text-xs text-muted-foreground\">{helpText}</p>\n )}\n </div>\n )}\n />\n )\n}\n","import { Controller } from 'react-hook-form'\nimport type { FieldValues } from 'react-hook-form'\nimport type { FormSelectProps } from './form-types'\n\n/**\n * Smart Form Select component\n *\n * @example\n * ```tsx\n * <FormSelect\n * name=\"country\"\n * label=\"Country\"\n * required\n * control={form.control}\n * options={[\n * { value: 'us', label: 'United States' },\n * { value: 'uk', label: 'United Kingdom' },\n * ]}\n * />\n * ```\n */\nexport function FormSelect<TFieldValues extends FieldValues = FieldValues>({\n name,\n label,\n options,\n placeholder,\n required = false,\n helpText,\n disabled = false,\n className,\n control,\n}: FormSelectProps<TFieldValues>) {\n return (\n <Controller\n name={name}\n control={control}\n render={({ field, fieldState: { error } }) => (\n <div className={`space-y-2 ${className || ''}`}>\n <label htmlFor={String(name)} className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n\n <select\n id={String(name)}\n disabled={disabled}\n className={`flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${\n error ? 'border-destructive' : ''\n }`}\n aria-invalid={!!error}\n {...field}\n value={field.value || ''}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map((option) => (\n <option\n key={String(option.value)}\n value={option.value}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </select>\n\n {error && (\n <p className=\"text-sm text-destructive\">{error.message}</p>\n )}\n\n {helpText && !error && (\n <p className=\"text-xs text-muted-foreground\">{helpText}</p>\n )}\n </div>\n )}\n />\n )\n}\n","import { Controller } from 'react-hook-form'\nimport type { FieldValues } from 'react-hook-form'\nimport type { FormCheckboxProps } from './form-types'\n\n/**\n * Smart Form Checkbox component\n *\n * @example\n * ```tsx\n * <FormCheckbox\n * name=\"acceptTerms\"\n * label=\"I accept the terms and conditions\"\n * required\n * control={form.control}\n * description=\"You must accept the terms to continue\"\n * />\n * ```\n */\nexport function FormCheckbox<TFieldValues extends FieldValues = FieldValues>({\n name,\n label,\n description,\n required = false,\n helpText,\n disabled = false,\n className,\n control,\n}: FormCheckboxProps<TFieldValues>) {\n return (\n <Controller\n name={name}\n control={control}\n render={({ field, fieldState: { error } }) => (\n <div className={`space-y-2 ${className || ''}`}>\n <div className=\"flex items-start space-x-3\">\n <input\n id={String(name)}\n type=\"checkbox\"\n disabled={disabled}\n className={`h-4 w-4 rounded border-input ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${\n error ? 'border-destructive' : ''\n }`}\n aria-invalid={!!error}\n checked={field.value || false}\n onChange={(e) => field.onChange(e.target.checked)}\n onBlur={field.onBlur}\n />\n <div className=\"flex-1 space-y-1 leading-none\">\n <label\n htmlFor={String(name)}\n className=\"text-sm font-medium cursor-pointer peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n </div>\n </div>\n\n {error && (\n <p className=\"text-sm text-destructive\">{error.message}</p>\n )}\n\n {helpText && !error && (\n <p className=\"text-xs text-muted-foreground\">{helpText}</p>\n )}\n </div>\n )}\n />\n )\n}\n","import * as React from 'react'\n\nexport interface FormLayoutProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Number of columns for the form layout\n * @default 1\n */\n columns?: 1 | 2 | 3 | 4\n\n /**\n * Spacing between form fields\n * @default \"md\"\n */\n spacing?: 'sm' | 'md' | 'lg'\n\n /**\n * Make the layout responsive (mobile: 1 col, tablet: 2 cols, desktop: specified cols)\n * @default true\n */\n responsive?: boolean\n}\n\nconst spacingClasses = {\n sm: 'gap-3',\n md: 'gap-4',\n lg: 'gap-6',\n}\n\nconst columnClasses = {\n responsive: {\n 1: 'grid-cols-1',\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',\n },\n fixed: {\n 1: 'grid-cols-1',\n 2: 'grid-cols-2',\n 3: 'grid-cols-3',\n 4: 'grid-cols-4',\n },\n}\n\n/**\n * FormLayout - Ready-to-use form grid layout\n *\n * @example\n * ```tsx\n * <FormLayout columns={2}>\n * <FormField name=\"firstName\" label=\"First Name\" control={form.control} />\n * <FormField name=\"lastName\" label=\"Last Name\" control={form.control} />\n * </FormLayout>\n * ```\n */\nexport function FormLayout({\n columns = 1,\n spacing = 'md',\n responsive = true,\n className = '',\n children,\n ...props\n}: FormLayoutProps) {\n const gridClasses = responsive ? columnClasses.responsive[columns] : columnClasses.fixed[columns]\n\n return (\n <div\n className={`grid ${gridClasses} ${spacingClasses[spacing]} ${className}`}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nFormLayout.displayName = 'FormLayout'\n","import * as React from 'react'\n\nexport interface FormSectionProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Section title\n */\n title?: string\n\n /**\n * Section description\n */\n description?: string\n\n /**\n * Number of columns for this section\n * @default 1\n */\n columns?: 1 | 2 | 3 | 4\n\n /**\n * Spacing between fields\n * @default \"md\"\n */\n spacing?: 'sm' | 'md' | 'lg'\n}\n\nconst spacingClasses = {\n sm: 'gap-3',\n md: 'gap-4',\n lg: 'gap-6',\n}\n\nconst columnClasses = {\n 1: 'grid-cols-1',\n 2: 'grid-cols-1 sm:grid-cols-2',\n 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',\n}\n\n/**\n * FormSection - Section with title and grid layout\n *\n * @example\n * ```tsx\n * <FormSection title=\"Personal Info\" description=\"Enter your details\" columns={2}>\n * <FormField name=\"name\" label=\"Name\" control={form.control} />\n * <FormField name=\"email\" label=\"Email\" control={form.control} />\n * </FormSection>\n * ```\n */\nexport function FormSection({\n title,\n description,\n columns = 1,\n spacing = 'md',\n className = '',\n children,\n ...props\n}: FormSectionProps) {\n return (\n <div className={`space-y-4 ${className}`} {...props}>\n {(title || description) && (\n <div className=\"space-y-1\">\n {title && (\n <h3 className=\"text-lg font-semibold leading-none tracking-tight\">\n {title}\n </h3>\n )}\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n </div>\n )}\n <div className={`grid ${columnClasses[columns]} ${spacingClasses[spacing]}`}>\n {children}\n </div>\n </div>\n )\n}\n\nFormSection.displayName = 'FormSection'\n","import * as React from 'react'\n\nexport interface FormGridProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Spacing between items\n * @default \"md\"\n */\n spacing?: 'sm' | 'md' | 'lg'\n}\n\nexport interface FormGridItemProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Column span for the item\n * @default 1\n */\n colSpan?: 1 | 2 | 3 | 4 | 'full'\n}\n\nconst spacingClasses = {\n sm: 'gap-3',\n md: 'gap-4',\n lg: 'gap-6',\n}\n\nconst colSpanClasses = {\n 1: 'col-span-1',\n 2: 'col-span-1 sm:col-span-2',\n 3: 'col-span-1 sm:col-span-2 lg:col-span-3',\n 4: 'col-span-1 sm:col-span-2 lg:col-span-4',\n full: 'col-span-full',\n}\n\n/**\n * FormGrid - Advanced grid layout with col-span support\n *\n * @example\n * ```tsx\n * <FormGrid>\n * <FormGridItem>\n * <FormField name=\"firstName\" label=\"First Name\" control={form.control} />\n * </FormGridItem>\n * <FormGridItem>\n * <FormField name=\"lastName\" label=\"Last Name\" control={form.control} />\n * </FormGridItem>\n * <FormGridItem colSpan=\"full\">\n * <FormField name=\"bio\" label=\"Bio\" control={form.control} />\n * </FormGridItem>\n * </FormGrid>\n * ```\n */\nexport function FormGrid({\n spacing = 'md',\n className = '',\n children,\n ...props\n}: FormGridProps) {\n return (\n <div\n className={`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 ${spacingClasses[spacing]} ${className}`}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nFormGrid.displayName = 'FormGrid'\n\n/**\n * FormGridItem - Item within FormGrid with custom column span\n */\nexport function FormGridItem({\n colSpan = 1,\n className = '',\n children,\n ...props\n}: FormGridItemProps) {\n return (\n <div className={`${colSpanClasses[colSpan]} ${className}`} {...props}>\n {children}\n </div>\n )\n}\n\nFormGridItem.displayName = 'FormGridItem'\n","import { useFieldArray as rhfUseFieldArray } from 'react-hook-form'\nimport type { FieldValues, ArrayPath } from 'react-hook-form'\nimport type { UseFormReturn } from 'react-hook-form'\n\n/**\n * Field array options\n */\nexport interface FieldArrayOptions<TFieldValues extends FieldValues = FieldValues> {\n /**\n * Field array name\n */\n name: ArrayPath<TFieldValues>\n\n /**\n * Form control instance\n */\n control: UseFormReturn<TFieldValues>['control']\n\n /**\n * Default value for new items\n */\n defaultValue?: unknown\n}\n\n/**\n * Wrapper around React Hook Form's useFieldArray with smart defaults\n *\n * @example\n * ```tsx\n * const { fields, append, remove } = useSmartFieldArray({\n * name: 'items',\n * control: form.control,\n * defaultValue: { name: '', quantity: 0 }\n * })\n * ```\n */\nexport function useSmartFieldArray<TFieldValues extends FieldValues = FieldValues>({\n name,\n control,\n defaultValue,\n}: FieldArrayOptions<TFieldValues>) {\n const fieldArray = rhfUseFieldArray({\n name,\n control,\n })\n\n const { append: rhfAppend, ...rest } = fieldArray\n\n // Enhanced append with default value\n const append = (value?: unknown) => {\n rhfAppend((value || defaultValue) as never)\n }\n\n return {\n ...rest,\n append,\n }\n}\n"]}
|