@rachelallyson/hero-hook-form 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/cypress/index.js +57 -29
- package/dist/index.d.ts +7 -3
- package/dist/index.js +30 -26
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.js +30 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.1.2] - 2025-01-28
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Date field helper**: Added `FormFieldHelpers.date()` method for creating date fields in forms
|
|
10
|
+
- Supports optional `dateProps` parameter for customizing the date input component
|
|
11
|
+
- Comprehensive test coverage for date field functionality
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **ZodForm FormProvider**: Wrapped ZodForm component with FormProvider to ensure form context is properly available
|
|
16
|
+
- Fixes issues with form context not being accessible in nested components
|
|
17
|
+
|
|
18
|
+
## [2.1.1] - 2025-01-28
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **ServerActionForm imports**: Use `#ui` alias for HeroUI imports to support both `@heroui/react` and individual package imports
|
|
23
|
+
- Ensures compatibility across different HeroUI installation patterns
|
|
24
|
+
|
|
5
25
|
## [2.1.0] - 2025-01-28
|
|
6
26
|
|
|
7
27
|
### Added
|
package/dist/cypress/index.js
CHANGED
|
@@ -293,48 +293,72 @@ function expectNoValidationErrors() {
|
|
|
293
293
|
return cy.get("body").should("not.contain", "error").and("not.contain", "invalid");
|
|
294
294
|
}
|
|
295
295
|
function expectFieldError(fieldLabel, errorMessage) {
|
|
296
|
-
|
|
296
|
+
const fieldContainer = cy.contains("label", fieldLabel).closest("div");
|
|
297
|
+
if (errorMessage) {
|
|
298
|
+
return fieldContainer.should("contain", errorMessage);
|
|
299
|
+
}
|
|
300
|
+
return fieldContainer.should(($div) => {
|
|
301
|
+
const text = $div.text();
|
|
302
|
+
const hasError = text.includes("error") || text.includes("invalid") || text.includes("required") || $div.find('[class*="error"], [class*="invalid"], [class*="danger"]').length > 0;
|
|
303
|
+
expect(hasError, "Field should have an error").to.be.true;
|
|
304
|
+
});
|
|
297
305
|
}
|
|
298
306
|
function expectFieldValid(fieldLabel) {
|
|
299
307
|
return cy.contains("label", fieldLabel).closest("div").should("not.contain", "error").and("not.contain", "invalid");
|
|
300
308
|
}
|
|
301
309
|
function triggerValidation(submitButton = false) {
|
|
302
310
|
if (submitButton) {
|
|
303
|
-
return
|
|
311
|
+
return withRetry(() => {
|
|
312
|
+
cy.get("form").should("exist");
|
|
313
|
+
cy.get(HERO_UI_SELECTORS.button.submit).first().should("be.visible").should("not.be.disabled").click();
|
|
314
|
+
return cy.get("form");
|
|
315
|
+
}, DEFAULT_CONFIG);
|
|
304
316
|
}
|
|
305
317
|
return cy.get("input").first().blur();
|
|
306
318
|
}
|
|
307
319
|
function submitForm() {
|
|
308
|
-
return
|
|
320
|
+
return withRetry(() => {
|
|
321
|
+
cy.get("form").should("exist");
|
|
322
|
+
cy.get(HERO_UI_SELECTORS.button.submit).first().should("be.visible").should("not.be.disabled").click();
|
|
323
|
+
return cy.get("form");
|
|
324
|
+
}, DEFAULT_CONFIG);
|
|
309
325
|
}
|
|
310
326
|
function submitAndExpectSuccess(successIndicator) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
327
|
+
return withRetry(() => {
|
|
328
|
+
cy.get("form").should("exist");
|
|
329
|
+
cy.get(HERO_UI_SELECTORS.button.submit).first().should("be.visible").should("not.be.disabled").click();
|
|
330
|
+
if (successIndicator) {
|
|
331
|
+
cy.contains(successIndicator).should("be.visible");
|
|
332
|
+
} else {
|
|
333
|
+
cy.get("body").should("contain.one.of", ["success", "submitted", "complete", "thank you"]);
|
|
334
|
+
}
|
|
335
|
+
return cy.get("form");
|
|
336
|
+
}, DEFAULT_CONFIG);
|
|
316
337
|
}
|
|
317
338
|
function submitAndExpectErrors(errorMessage, formIndex = 0) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
cy.
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
cy.log("
|
|
329
|
-
|
|
330
|
-
cy.log(
|
|
339
|
+
return withRetry(() => {
|
|
340
|
+
cy.get("form").should("exist");
|
|
341
|
+
cy.get(HERO_UI_SELECTORS.button.submit).eq(formIndex).should("be.visible").should("not.be.disabled").click();
|
|
342
|
+
cy.get("form").should("exist");
|
|
343
|
+
cy.wait(500);
|
|
344
|
+
if (errorMessage) {
|
|
345
|
+
cy.get("body").then(($body) => {
|
|
346
|
+
if ($body.text().includes(errorMessage)) {
|
|
347
|
+
cy.contains(errorMessage).should("be.visible");
|
|
348
|
+
} else {
|
|
349
|
+
cy.log("Expected error message not found:", errorMessage);
|
|
350
|
+
cy.get('[class*="text-danger"], [class*="text-red"], [class*="error"]').then(($errors) => {
|
|
351
|
+
cy.log("Found validation errors:", $errors.length);
|
|
352
|
+
$errors.each((index, error) => {
|
|
353
|
+
cy.log(`Error ${index}:`, error.textContent);
|
|
354
|
+
});
|
|
331
355
|
});
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
|
|
356
|
+
cy.contains(errorMessage).should("be.visible");
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
return cy.get("form");
|
|
361
|
+
}, DEFAULT_CONFIG);
|
|
338
362
|
}
|
|
339
363
|
function resetForm() {
|
|
340
364
|
return cy.get("body").then(($body) => {
|
|
@@ -348,7 +372,11 @@ function resetForm() {
|
|
|
348
372
|
}
|
|
349
373
|
function interceptFormSubmission(method, url, alias) {
|
|
350
374
|
cy.intercept(method, url).as(alias);
|
|
351
|
-
return
|
|
375
|
+
return withRetry(() => {
|
|
376
|
+
cy.get("form").should("exist");
|
|
377
|
+
cy.get(HERO_UI_SELECTORS.button.submit).first().should("be.visible").should("not.be.disabled").click();
|
|
378
|
+
return cy.get("form");
|
|
379
|
+
}, DEFAULT_CONFIG);
|
|
352
380
|
}
|
|
353
381
|
function verifyFormExists() {
|
|
354
382
|
return cy.get("form").should("exist");
|
|
@@ -365,7 +393,7 @@ function verifyFieldCount(selector, count) {
|
|
|
365
393
|
return cy.get(selector).filter(":visible").not('[type="hidden"]').should("have.length", count);
|
|
366
394
|
}
|
|
367
395
|
function getFormData() {
|
|
368
|
-
return extractFormData();
|
|
396
|
+
return extractFormData().then((data) => data);
|
|
369
397
|
}
|
|
370
398
|
function fillCompleteForm(formData) {
|
|
371
399
|
return cy.then(() => {
|
package/dist/index.d.ts
CHANGED
|
@@ -12,9 +12,9 @@ import { Input, Textarea } from '@heroui/input';
|
|
|
12
12
|
import { RadioGroup } from '@heroui/radio';
|
|
13
13
|
import { Select } from '@heroui/select';
|
|
14
14
|
import { Switch } from '@heroui/switch';
|
|
15
|
+
import { Button as Button$1 } from '@heroui/button';
|
|
15
16
|
import { DateInput } from '@heroui/date-input';
|
|
16
17
|
import { Slider } from '@heroui/slider';
|
|
17
|
-
import { Button as Button$1 } from '@heroui/button';
|
|
18
18
|
|
|
19
19
|
interface FieldBaseProps<TFieldValues extends FieldValues, TValue> {
|
|
20
20
|
name: Path<TFieldValues>;
|
|
@@ -271,7 +271,7 @@ interface ServerActionFormProps<T extends FieldValues> {
|
|
|
271
271
|
resetButtonText?: string;
|
|
272
272
|
showResetButton?: boolean;
|
|
273
273
|
spacing?: "2" | "4" | "6" | "8" | "lg";
|
|
274
|
-
submitButtonProps?: Partial<React$1.ComponentProps<typeof Button>>;
|
|
274
|
+
submitButtonProps?: Partial<React$1.ComponentProps<typeof Button$1>>;
|
|
275
275
|
submitButtonText?: string;
|
|
276
276
|
subtitle?: string;
|
|
277
277
|
title?: string;
|
|
@@ -724,7 +724,7 @@ interface ZodFormProps<T extends FieldValues> {
|
|
|
724
724
|
values: T;
|
|
725
725
|
}) => React$1.ReactNode;
|
|
726
726
|
}
|
|
727
|
-
declare function ZodForm<T extends FieldValues>({ className, columns, config, layout, onError, onSubmit, onSuccess, render, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: ZodFormProps<T>):
|
|
727
|
+
declare function ZodForm<T extends FieldValues>({ className, columns, config, layout, onError, onSubmit, onSuccess, render, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: ZodFormProps<T>): React$1.JSX.Element;
|
|
728
728
|
|
|
729
729
|
/**
|
|
730
730
|
* Hook for using Zod validation with React Hook Form
|
|
@@ -781,6 +781,10 @@ declare const FormFieldHelpers: {
|
|
|
781
781
|
* Create a checkbox field
|
|
782
782
|
*/
|
|
783
783
|
checkbox: <T extends FieldValues>(name: Path<T>, label: string) => ZodFormFieldConfig<T>;
|
|
784
|
+
/**
|
|
785
|
+
* Create a date field
|
|
786
|
+
*/
|
|
787
|
+
date: <T extends FieldValues>(name: Path<T>, label: string, dateProps?: Record<string, string | number | boolean>) => ZodFormFieldConfig<T>;
|
|
784
788
|
/**
|
|
785
789
|
* Create an input field
|
|
786
790
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1238,14 +1238,6 @@ function ConfigurableForm({
|
|
|
1238
1238
|
|
|
1239
1239
|
// src/components/ServerActionForm.tsx
|
|
1240
1240
|
import React17 from "react";
|
|
1241
|
-
import {
|
|
1242
|
-
Button as Button4,
|
|
1243
|
-
Checkbox as Checkbox2,
|
|
1244
|
-
Input as Input2,
|
|
1245
|
-
Select as Select2,
|
|
1246
|
-
SelectItem as SelectItem2,
|
|
1247
|
-
Textarea as Textarea2
|
|
1248
|
-
} from "@heroui/react";
|
|
1249
1241
|
import { useActionState } from "react";
|
|
1250
1242
|
function ServerActionForm({
|
|
1251
1243
|
action,
|
|
@@ -1393,7 +1385,7 @@ function ServerActionForm({
|
|
|
1393
1385
|
),
|
|
1394
1386
|
renderFields(),
|
|
1395
1387
|
/* @__PURE__ */ React17.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React17.createElement(
|
|
1396
|
-
|
|
1388
|
+
Button,
|
|
1397
1389
|
{
|
|
1398
1390
|
color: "primary",
|
|
1399
1391
|
isDisabled: pending,
|
|
@@ -1403,7 +1395,7 @@ function ServerActionForm({
|
|
|
1403
1395
|
},
|
|
1404
1396
|
submitButtonText
|
|
1405
1397
|
), showResetButton && /* @__PURE__ */ React17.createElement(
|
|
1406
|
-
|
|
1398
|
+
Button,
|
|
1407
1399
|
{
|
|
1408
1400
|
isDisabled: pending,
|
|
1409
1401
|
type: "button",
|
|
@@ -1478,7 +1470,7 @@ function ServerActionField({
|
|
|
1478
1470
|
case "input": {
|
|
1479
1471
|
const inputType = field2.inputProps?.type || "text";
|
|
1480
1472
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1481
|
-
|
|
1473
|
+
Input,
|
|
1482
1474
|
{
|
|
1483
1475
|
...field2.inputProps,
|
|
1484
1476
|
"data-field-name": fieldName,
|
|
@@ -1495,7 +1487,7 @@ function ServerActionField({
|
|
|
1495
1487
|
}
|
|
1496
1488
|
case "textarea": {
|
|
1497
1489
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1498
|
-
|
|
1490
|
+
Textarea,
|
|
1499
1491
|
{
|
|
1500
1492
|
...field2.textareaProps,
|
|
1501
1493
|
"data-field-name": fieldName,
|
|
@@ -1511,7 +1503,7 @@ function ServerActionField({
|
|
|
1511
1503
|
}
|
|
1512
1504
|
case "checkbox": {
|
|
1513
1505
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value: checked ? "on" : "" }), /* @__PURE__ */ React17.createElement(
|
|
1514
|
-
|
|
1506
|
+
Checkbox,
|
|
1515
1507
|
{
|
|
1516
1508
|
...field2.checkboxProps,
|
|
1517
1509
|
"data-field-name": fieldName,
|
|
@@ -1527,7 +1519,7 @@ function ServerActionField({
|
|
|
1527
1519
|
case "select": {
|
|
1528
1520
|
const options = field2.options || [];
|
|
1529
1521
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1530
|
-
|
|
1522
|
+
Select,
|
|
1531
1523
|
{
|
|
1532
1524
|
...field2.selectProps,
|
|
1533
1525
|
"data-field-name": fieldName,
|
|
@@ -1543,13 +1535,13 @@ function ServerActionField({
|
|
|
1543
1535
|
}
|
|
1544
1536
|
},
|
|
1545
1537
|
options.map(
|
|
1546
|
-
(option) => /* @__PURE__ */ React17.createElement(
|
|
1538
|
+
(option) => /* @__PURE__ */ React17.createElement(SelectItem, { key: String(option.value) }, option.label)
|
|
1547
1539
|
)
|
|
1548
1540
|
));
|
|
1549
1541
|
}
|
|
1550
1542
|
default:
|
|
1551
1543
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1552
|
-
|
|
1544
|
+
Input,
|
|
1553
1545
|
{
|
|
1554
1546
|
"data-field-name": fieldName,
|
|
1555
1547
|
label: field2.label,
|
|
@@ -1862,7 +1854,10 @@ import { useFormContext as useFormContext5 } from "react-hook-form";
|
|
|
1862
1854
|
|
|
1863
1855
|
// src/components/ZodForm.tsx
|
|
1864
1856
|
import React21 from "react";
|
|
1865
|
-
import { Button as
|
|
1857
|
+
import { Button as Button5 } from "@heroui/react";
|
|
1858
|
+
import {
|
|
1859
|
+
FormProvider as FormProvider2
|
|
1860
|
+
} from "react-hook-form";
|
|
1866
1861
|
|
|
1867
1862
|
// src/zod-integration.ts
|
|
1868
1863
|
import { useForm as useForm2 } from "react-hook-form";
|
|
@@ -1982,7 +1977,7 @@ function useEnhancedFormState(form, options = {}) {
|
|
|
1982
1977
|
|
|
1983
1978
|
// src/components/FormStatus.tsx
|
|
1984
1979
|
import React20 from "react";
|
|
1985
|
-
import { Button as
|
|
1980
|
+
import { Button as Button4 } from "@heroui/react";
|
|
1986
1981
|
function FormStatus({
|
|
1987
1982
|
className = "",
|
|
1988
1983
|
onDismiss,
|
|
@@ -2013,7 +2008,7 @@ function FormStatus({
|
|
|
2013
2008
|
/* @__PURE__ */ React20.createElement("span", { className: "text-green-600" }, "\u2705"),
|
|
2014
2009
|
/* @__PURE__ */ React20.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20.createElement("p", { className: "text-sm font-medium text-green-900" }, "Form submitted successfully!"), showDetails && submittedData && /* @__PURE__ */ React20.createElement("p", { className: "text-xs text-green-700" }, "Your data has been saved. Thank you for your submission.")),
|
|
2015
2010
|
onDismiss && /* @__PURE__ */ React20.createElement(
|
|
2016
|
-
|
|
2011
|
+
Button4,
|
|
2017
2012
|
{
|
|
2018
2013
|
size: "sm",
|
|
2019
2014
|
variant: "light",
|
|
@@ -2035,7 +2030,7 @@ function FormStatus({
|
|
|
2035
2030
|
/* @__PURE__ */ React20.createElement("span", { className: "text-red-600" }, "\u26A0\uFE0F"),
|
|
2036
2031
|
/* @__PURE__ */ React20.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20.createElement("p", { className: "text-sm font-medium text-red-900" }, "Error submitting form"), /* @__PURE__ */ React20.createElement("p", { className: "text-xs text-red-700" }, error)),
|
|
2037
2032
|
onDismiss && /* @__PURE__ */ React20.createElement(
|
|
2038
|
-
|
|
2033
|
+
Button4,
|
|
2039
2034
|
{
|
|
2040
2035
|
size: "sm",
|
|
2041
2036
|
variant: "light",
|
|
@@ -2190,16 +2185,16 @@ function ZodForm({
|
|
|
2190
2185
|
}
|
|
2191
2186
|
}, [form.formState.errors, config.onError]);
|
|
2192
2187
|
if (render) {
|
|
2193
|
-
return render({
|
|
2188
|
+
return /* @__PURE__ */ React21.createElement(FormProvider2, { ...form }, render({
|
|
2194
2189
|
errors: form.formState.errors,
|
|
2195
2190
|
form,
|
|
2196
2191
|
isSubmitted: enhancedState.status !== "idle",
|
|
2197
2192
|
isSubmitting: enhancedState.isSubmitting,
|
|
2198
2193
|
isSuccess: enhancedState.isSuccess,
|
|
2199
2194
|
values: form.getValues()
|
|
2200
|
-
});
|
|
2195
|
+
}));
|
|
2201
2196
|
}
|
|
2202
|
-
return /* @__PURE__ */ React21.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), /* @__PURE__ */ React21.createElement(
|
|
2197
|
+
return /* @__PURE__ */ React21.createElement(FormProvider2, { ...form }, /* @__PURE__ */ React21.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), /* @__PURE__ */ React21.createElement(
|
|
2203
2198
|
FormStatus,
|
|
2204
2199
|
{
|
|
2205
2200
|
state: enhancedState,
|
|
@@ -2207,7 +2202,7 @@ function ZodForm({
|
|
|
2207
2202
|
showDetails: true
|
|
2208
2203
|
}
|
|
2209
2204
|
), renderFields(), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React21.createElement(
|
|
2210
|
-
|
|
2205
|
+
Button5,
|
|
2211
2206
|
{
|
|
2212
2207
|
color: "primary",
|
|
2213
2208
|
isDisabled: enhancedState.isSubmitting,
|
|
@@ -2217,7 +2212,7 @@ function ZodForm({
|
|
|
2217
2212
|
},
|
|
2218
2213
|
enhancedState.isSuccess ? "Success!" : submitButtonText
|
|
2219
2214
|
), showResetButton && /* @__PURE__ */ React21.createElement(
|
|
2220
|
-
|
|
2215
|
+
Button5,
|
|
2221
2216
|
{
|
|
2222
2217
|
isDisabled: enhancedState.isSubmitting,
|
|
2223
2218
|
type: "button",
|
|
@@ -2225,7 +2220,7 @@ function ZodForm({
|
|
|
2225
2220
|
onPress: resetForm
|
|
2226
2221
|
},
|
|
2227
2222
|
resetButtonText
|
|
2228
|
-
)));
|
|
2223
|
+
))));
|
|
2229
2224
|
}
|
|
2230
2225
|
|
|
2231
2226
|
// src/builders/BasicFormBuilder.ts
|
|
@@ -2310,6 +2305,15 @@ var FormFieldHelpers = {
|
|
|
2310
2305
|
name,
|
|
2311
2306
|
type: "checkbox"
|
|
2312
2307
|
}),
|
|
2308
|
+
/**
|
|
2309
|
+
* Create a date field
|
|
2310
|
+
*/
|
|
2311
|
+
date: (name, label, dateProps) => ({
|
|
2312
|
+
dateProps,
|
|
2313
|
+
label,
|
|
2314
|
+
name,
|
|
2315
|
+
type: "date"
|
|
2316
|
+
}),
|
|
2313
2317
|
/**
|
|
2314
2318
|
* Create an input field
|
|
2315
2319
|
*/
|
package/dist/react/index.d.ts
CHANGED
|
@@ -716,7 +716,7 @@ interface ZodFormProps<T extends FieldValues> {
|
|
|
716
716
|
values: T;
|
|
717
717
|
}) => React$1.ReactNode;
|
|
718
718
|
}
|
|
719
|
-
declare function ZodForm<T extends FieldValues>({ className, columns, config, layout, onError, onSubmit, onSuccess, render, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: ZodFormProps<T>):
|
|
719
|
+
declare function ZodForm<T extends FieldValues>({ className, columns, config, layout, onError, onSubmit, onSuccess, render, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: ZodFormProps<T>): React$1.JSX.Element;
|
|
720
720
|
|
|
721
721
|
/**
|
|
722
722
|
* Hook for using Zod validation with React Hook Form
|
|
@@ -773,6 +773,10 @@ declare const FormFieldHelpers: {
|
|
|
773
773
|
* Create a checkbox field
|
|
774
774
|
*/
|
|
775
775
|
checkbox: <T extends FieldValues>(name: Path<T>, label: string) => ZodFormFieldConfig<T>;
|
|
776
|
+
/**
|
|
777
|
+
* Create a date field
|
|
778
|
+
*/
|
|
779
|
+
date: <T extends FieldValues>(name: Path<T>, label: string, dateProps?: Record<string, string | number | boolean>) => ZodFormFieldConfig<T>;
|
|
776
780
|
/**
|
|
777
781
|
* Create an input field
|
|
778
782
|
*/
|
package/dist/react/index.js
CHANGED
|
@@ -1243,14 +1243,6 @@ function ConfigurableForm({
|
|
|
1243
1243
|
|
|
1244
1244
|
// src/components/ServerActionForm.tsx
|
|
1245
1245
|
import React17 from "react";
|
|
1246
|
-
import {
|
|
1247
|
-
Button as Button4,
|
|
1248
|
-
Checkbox as Checkbox2,
|
|
1249
|
-
Input as Input2,
|
|
1250
|
-
Select as Select2,
|
|
1251
|
-
SelectItem as SelectItem2,
|
|
1252
|
-
Textarea as Textarea2
|
|
1253
|
-
} from "@heroui/react";
|
|
1254
1246
|
import { useActionState } from "react";
|
|
1255
1247
|
function ServerActionForm({
|
|
1256
1248
|
action,
|
|
@@ -1398,7 +1390,7 @@ function ServerActionForm({
|
|
|
1398
1390
|
),
|
|
1399
1391
|
renderFields(),
|
|
1400
1392
|
/* @__PURE__ */ React17.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React17.createElement(
|
|
1401
|
-
|
|
1393
|
+
Button,
|
|
1402
1394
|
{
|
|
1403
1395
|
color: "primary",
|
|
1404
1396
|
isDisabled: pending,
|
|
@@ -1408,7 +1400,7 @@ function ServerActionForm({
|
|
|
1408
1400
|
},
|
|
1409
1401
|
submitButtonText
|
|
1410
1402
|
), showResetButton && /* @__PURE__ */ React17.createElement(
|
|
1411
|
-
|
|
1403
|
+
Button,
|
|
1412
1404
|
{
|
|
1413
1405
|
isDisabled: pending,
|
|
1414
1406
|
type: "button",
|
|
@@ -1483,7 +1475,7 @@ function ServerActionField({
|
|
|
1483
1475
|
case "input": {
|
|
1484
1476
|
const inputType = field2.inputProps?.type || "text";
|
|
1485
1477
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1486
|
-
|
|
1478
|
+
Input,
|
|
1487
1479
|
{
|
|
1488
1480
|
...field2.inputProps,
|
|
1489
1481
|
"data-field-name": fieldName,
|
|
@@ -1500,7 +1492,7 @@ function ServerActionField({
|
|
|
1500
1492
|
}
|
|
1501
1493
|
case "textarea": {
|
|
1502
1494
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1503
|
-
|
|
1495
|
+
Textarea,
|
|
1504
1496
|
{
|
|
1505
1497
|
...field2.textareaProps,
|
|
1506
1498
|
"data-field-name": fieldName,
|
|
@@ -1516,7 +1508,7 @@ function ServerActionField({
|
|
|
1516
1508
|
}
|
|
1517
1509
|
case "checkbox": {
|
|
1518
1510
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value: checked ? "on" : "" }), /* @__PURE__ */ React17.createElement(
|
|
1519
|
-
|
|
1511
|
+
Checkbox,
|
|
1520
1512
|
{
|
|
1521
1513
|
...field2.checkboxProps,
|
|
1522
1514
|
"data-field-name": fieldName,
|
|
@@ -1532,7 +1524,7 @@ function ServerActionField({
|
|
|
1532
1524
|
case "select": {
|
|
1533
1525
|
const options = field2.options || [];
|
|
1534
1526
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1535
|
-
|
|
1527
|
+
Select,
|
|
1536
1528
|
{
|
|
1537
1529
|
...field2.selectProps,
|
|
1538
1530
|
"data-field-name": fieldName,
|
|
@@ -1548,13 +1540,13 @@ function ServerActionField({
|
|
|
1548
1540
|
}
|
|
1549
1541
|
},
|
|
1550
1542
|
options.map(
|
|
1551
|
-
(option) => /* @__PURE__ */ React17.createElement(
|
|
1543
|
+
(option) => /* @__PURE__ */ React17.createElement(SelectItem, { key: String(option.value) }, option.label)
|
|
1552
1544
|
)
|
|
1553
1545
|
));
|
|
1554
1546
|
}
|
|
1555
1547
|
default:
|
|
1556
1548
|
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
|
|
1557
|
-
|
|
1549
|
+
Input,
|
|
1558
1550
|
{
|
|
1559
1551
|
"data-field-name": fieldName,
|
|
1560
1552
|
label: field2.label,
|
|
@@ -1867,7 +1859,10 @@ import { useFormContext as useFormContext5 } from "react-hook-form";
|
|
|
1867
1859
|
|
|
1868
1860
|
// src/components/ZodForm.tsx
|
|
1869
1861
|
import React21 from "react";
|
|
1870
|
-
import { Button as
|
|
1862
|
+
import { Button as Button5 } from "@heroui/react";
|
|
1863
|
+
import {
|
|
1864
|
+
FormProvider as FormProvider2
|
|
1865
|
+
} from "react-hook-form";
|
|
1871
1866
|
|
|
1872
1867
|
// src/zod-integration.ts
|
|
1873
1868
|
import { useForm as useForm2 } from "react-hook-form";
|
|
@@ -1987,7 +1982,7 @@ function useEnhancedFormState(form, options = {}) {
|
|
|
1987
1982
|
|
|
1988
1983
|
// src/components/FormStatus.tsx
|
|
1989
1984
|
import React20 from "react";
|
|
1990
|
-
import { Button as
|
|
1985
|
+
import { Button as Button4 } from "@heroui/react";
|
|
1991
1986
|
function FormStatus({
|
|
1992
1987
|
className = "",
|
|
1993
1988
|
onDismiss,
|
|
@@ -2018,7 +2013,7 @@ function FormStatus({
|
|
|
2018
2013
|
/* @__PURE__ */ React20.createElement("span", { className: "text-green-600" }, "\u2705"),
|
|
2019
2014
|
/* @__PURE__ */ React20.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20.createElement("p", { className: "text-sm font-medium text-green-900" }, "Form submitted successfully!"), showDetails && submittedData && /* @__PURE__ */ React20.createElement("p", { className: "text-xs text-green-700" }, "Your data has been saved. Thank you for your submission.")),
|
|
2020
2015
|
onDismiss && /* @__PURE__ */ React20.createElement(
|
|
2021
|
-
|
|
2016
|
+
Button4,
|
|
2022
2017
|
{
|
|
2023
2018
|
size: "sm",
|
|
2024
2019
|
variant: "light",
|
|
@@ -2040,7 +2035,7 @@ function FormStatus({
|
|
|
2040
2035
|
/* @__PURE__ */ React20.createElement("span", { className: "text-red-600" }, "\u26A0\uFE0F"),
|
|
2041
2036
|
/* @__PURE__ */ React20.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20.createElement("p", { className: "text-sm font-medium text-red-900" }, "Error submitting form"), /* @__PURE__ */ React20.createElement("p", { className: "text-xs text-red-700" }, error)),
|
|
2042
2037
|
onDismiss && /* @__PURE__ */ React20.createElement(
|
|
2043
|
-
|
|
2038
|
+
Button4,
|
|
2044
2039
|
{
|
|
2045
2040
|
size: "sm",
|
|
2046
2041
|
variant: "light",
|
|
@@ -2195,16 +2190,16 @@ function ZodForm({
|
|
|
2195
2190
|
}
|
|
2196
2191
|
}, [form.formState.errors, config.onError]);
|
|
2197
2192
|
if (render) {
|
|
2198
|
-
return render({
|
|
2193
|
+
return /* @__PURE__ */ React21.createElement(FormProvider2, { ...form }, render({
|
|
2199
2194
|
errors: form.formState.errors,
|
|
2200
2195
|
form,
|
|
2201
2196
|
isSubmitted: enhancedState.status !== "idle",
|
|
2202
2197
|
isSubmitting: enhancedState.isSubmitting,
|
|
2203
2198
|
isSuccess: enhancedState.isSuccess,
|
|
2204
2199
|
values: form.getValues()
|
|
2205
|
-
});
|
|
2200
|
+
}));
|
|
2206
2201
|
}
|
|
2207
|
-
return /* @__PURE__ */ React21.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), /* @__PURE__ */ React21.createElement(
|
|
2202
|
+
return /* @__PURE__ */ React21.createElement(FormProvider2, { ...form }, /* @__PURE__ */ React21.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), /* @__PURE__ */ React21.createElement(
|
|
2208
2203
|
FormStatus,
|
|
2209
2204
|
{
|
|
2210
2205
|
state: enhancedState,
|
|
@@ -2212,7 +2207,7 @@ function ZodForm({
|
|
|
2212
2207
|
showDetails: true
|
|
2213
2208
|
}
|
|
2214
2209
|
), renderFields(), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React21.createElement(
|
|
2215
|
-
|
|
2210
|
+
Button5,
|
|
2216
2211
|
{
|
|
2217
2212
|
color: "primary",
|
|
2218
2213
|
isDisabled: enhancedState.isSubmitting,
|
|
@@ -2222,7 +2217,7 @@ function ZodForm({
|
|
|
2222
2217
|
},
|
|
2223
2218
|
enhancedState.isSuccess ? "Success!" : submitButtonText
|
|
2224
2219
|
), showResetButton && /* @__PURE__ */ React21.createElement(
|
|
2225
|
-
|
|
2220
|
+
Button5,
|
|
2226
2221
|
{
|
|
2227
2222
|
isDisabled: enhancedState.isSubmitting,
|
|
2228
2223
|
type: "button",
|
|
@@ -2230,7 +2225,7 @@ function ZodForm({
|
|
|
2230
2225
|
onPress: resetForm
|
|
2231
2226
|
},
|
|
2232
2227
|
resetButtonText
|
|
2233
|
-
)));
|
|
2228
|
+
))));
|
|
2234
2229
|
}
|
|
2235
2230
|
|
|
2236
2231
|
// src/builders/BasicFormBuilder.ts
|
|
@@ -2315,6 +2310,15 @@ var FormFieldHelpers = {
|
|
|
2315
2310
|
name,
|
|
2316
2311
|
type: "checkbox"
|
|
2317
2312
|
}),
|
|
2313
|
+
/**
|
|
2314
|
+
* Create a date field
|
|
2315
|
+
*/
|
|
2316
|
+
date: (name, label, dateProps) => ({
|
|
2317
|
+
dateProps,
|
|
2318
|
+
label,
|
|
2319
|
+
name,
|
|
2320
|
+
type: "date"
|
|
2321
|
+
}),
|
|
2318
2322
|
/**
|
|
2319
2323
|
* Create an input field
|
|
2320
2324
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rachelallyson/hero-hook-form",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Typed form helpers that combine React Hook Form and HeroUI components.",
|
|
5
5
|
"author": "Rachel Higley",
|
|
6
6
|
"homepage": "https://rachelallyson.github.io/hero-hook-form/",
|