@rachelallyson/hero-hook-form 1.2.0 โ 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/dist/cypress/index.d.ts +141 -0
- package/dist/cypress/index.js +897 -0
- package/dist/index.d.ts +730 -5
- package/dist/index.js +1832 -220
- package/dist/react/index.d.ts +730 -5
- package/dist/react/index.js +1832 -220
- package/package.json +10 -3
- package/README.md +0 -412
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rachelallyson/hero-hook-form",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Typed form helpers that combine React Hook Form and HeroUI components.",
|
|
5
5
|
"author": "Rachel Higley",
|
|
6
6
|
"homepage": "https://github.com/rachelallyson/hero-hook-form#readme",
|
|
@@ -43,6 +43,10 @@
|
|
|
43
43
|
"./react": {
|
|
44
44
|
"types": "./dist/react/index.d.ts",
|
|
45
45
|
"import": "./dist/react/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./cypress": {
|
|
48
|
+
"types": "./dist/cypress/index.d.ts",
|
|
49
|
+
"import": "./dist/cypress/index.js"
|
|
46
50
|
}
|
|
47
51
|
},
|
|
48
52
|
"files": [
|
|
@@ -55,7 +59,7 @@
|
|
|
55
59
|
"node": ">=18.0.0"
|
|
56
60
|
},
|
|
57
61
|
"scripts": {
|
|
58
|
-
"build": "tsup src/index.ts --format esm --dts --clean && tsup src/index.ts --format esm --dts --env.NODE_ENV=production --tsconfig tsconfig.react.json --out-dir dist/react",
|
|
62
|
+
"build": "tsup src/index.ts --format esm --dts --clean && tsup src/index.ts --format esm --dts --env.NODE_ENV=production --tsconfig tsconfig.react.json --out-dir dist/react && tsup src/cypress/index.ts --format esm --dts --out-dir dist/cypress",
|
|
59
63
|
"dev:build": "tsup src/index.ts --format esm --dts --watch",
|
|
60
64
|
"lint": "eslint src",
|
|
61
65
|
"typecheck": "tsc --noEmit",
|
|
@@ -162,5 +166,8 @@
|
|
|
162
166
|
"@rachelallyson/heroui-font-picker": {
|
|
163
167
|
"optional": true
|
|
164
168
|
}
|
|
169
|
+
},
|
|
170
|
+
"dependencies": {
|
|
171
|
+
"@hookform/resolvers": "^5.2.2"
|
|
165
172
|
}
|
|
166
|
-
}
|
|
173
|
+
}
|
package/README.md
DELETED
|
@@ -1,412 +0,0 @@
|
|
|
1
|
-
# Hero Hook Form
|
|
2
|
-
|
|
3
|
-
[](https://badge.fury.io/js/%40rachelallyson%2Fhero-hook-form)
|
|
4
|
-
[](https://opensource.org/licenses/ISC)
|
|
5
|
-
[](https://www.typescriptlang.org/)
|
|
6
|
-
[](https://reactjs.org/)
|
|
7
|
-
[](https://heroui.com/)
|
|
8
|
-
|
|
9
|
-
> **Type-safe form components that combine React Hook Form with HeroUI's design system.**
|
|
10
|
-
|
|
11
|
-
Build beautiful, accessible forms with full TypeScript support, comprehensive validation, and HeroUI's modern design system. Perfect for React applications that need robust form handling with excellent developer experience.
|
|
12
|
-
|
|
13
|
-
## โจ Features
|
|
14
|
-
|
|
15
|
-
- ๐ฏ **Strongly-typed** field components with automatic TypeScript inference
|
|
16
|
-
- ๐๏ธ **Dual entrypoints** for maximum flexibility:
|
|
17
|
-
- Default entrypoint for individual HeroUI packages (better tree-shaking)
|
|
18
|
-
- `/react` entrypoint for the aggregate `@heroui/react` (convenient single dependency)
|
|
19
|
-
- ๐ฆ **Optional dependencies** - install only what you need
|
|
20
|
-
- ๐ง **Global configuration** system for consistent styling across your app
|
|
21
|
-
- โ
**Zod integration** for schema-based validation with type safety
|
|
22
|
-
- ๐จ **Multiple layouts** (vertical, horizontal, grid) with responsive design
|
|
23
|
-
- โฟ **Accessibility-first** with HeroUI's built-in ARIA support
|
|
24
|
-
- ๐ณ **Tree-shakeable** for optimal bundle sizes
|
|
25
|
-
- ๐ **Rapid prototyping** with ConfigurableForm component
|
|
26
|
-
- ๐จ **Optional font picker** with Google Fonts integration
|
|
27
|
-
|
|
28
|
-
## ๐ Quick Start
|
|
29
|
-
|
|
30
|
-
### Option 1: All-in-One HeroUI Package (Recommended for Development)
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npm install @rachelallyson/hero-hook-form @heroui/react react-hook-form zod
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Option 2: Individual HeroUI Packages (Recommended for Production)
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
npm install @rachelallyson/hero-hook-form react-hook-form zod
|
|
40
|
-
npm install @heroui/button @heroui/input @heroui/select # Only what you need
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Option 3: With Optional Font Picker
|
|
44
|
-
|
|
45
|
-
For advanced font selection with Google Fonts integration:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npm install @rachelallyson/hero-hook-form @rachelallyson/heroui-font-picker
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The `FontPickerField` will automatically use the font picker package if available, with a helpful fallback message if not installed.
|
|
52
|
-
|
|
53
|
-
### Basic Usage
|
|
54
|
-
|
|
55
|
-
```tsx
|
|
56
|
-
import { ZodForm } from "@rachelallyson/hero-hook-form";
|
|
57
|
-
import { z } from "zod";
|
|
58
|
-
|
|
59
|
-
const schema = z.object({
|
|
60
|
-
email: z.string().email("Invalid email"),
|
|
61
|
-
name: z.string().min(1, "Name is required"),
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const config = {
|
|
65
|
-
schema,
|
|
66
|
-
fields: [
|
|
67
|
-
{ name: "name", type: "input", label: "Name" },
|
|
68
|
-
{ name: "email", type: "input", label: "Email", inputProps: { type: "email" } },
|
|
69
|
-
],
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export function ContactForm() {
|
|
73
|
-
return <ZodForm config={config} onSubmit={console.log} />;
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
> ๐ **See [Installation Guide](./docs/installation.md) for detailed setup instructions and bundle optimization tips.**
|
|
78
|
-
|
|
79
|
-
## ๐ Why Hero Hook Form?
|
|
80
|
-
|
|
81
|
-
| Feature | Manual Setup | Hero Hook Form |
|
|
82
|
-
|---------|--------------|----------------|
|
|
83
|
-
| TypeScript | โ Manual types | โ
Automatic inference |
|
|
84
|
-
| Validation | โ Complex setup | โ
Built-in + Zod |
|
|
85
|
-
| Styling | โ Inconsistent | โ
Global defaults |
|
|
86
|
-
| Accessibility | โ Manual work | โ
HeroUI built-in |
|
|
87
|
-
| Bundle size | โ Large | โ
Tree-shakeable |
|
|
88
|
-
| Development | โ Slow | โ
Rapid prototyping |
|
|
89
|
-
|
|
90
|
-
## Requirements
|
|
91
|
-
|
|
92
|
-
- **React**: >=18.2 <20
|
|
93
|
-
- **React DOM**: >=18.2 <20
|
|
94
|
-
- **React Hook Form**: >=7 <8
|
|
95
|
-
- **HeroUI**: >=2 <3 (either individual packages or `@heroui/react`)
|
|
96
|
-
|
|
97
|
-
## Installation Options
|
|
98
|
-
|
|
99
|
-
### Option A: Individual HeroUI Packages (Recommended for Production)
|
|
100
|
-
|
|
101
|
-
Install only the HeroUI components you actually use for optimal bundle size:
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
# Minimal set that covers all included fields
|
|
105
|
-
npm i @rachelallyson/hero-hook-form react-hook-form \
|
|
106
|
-
@heroui/input @heroui/checkbox @heroui/radio @heroui/select \
|
|
107
|
-
@heroui/switch @heroui/button @heroui/spinner
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Import from the package root:
|
|
111
|
-
|
|
112
|
-
```tsx
|
|
113
|
-
import { InputField, SelectField, CheckboxField, RadioGroupField, SwitchField, TextareaField, SubmitButton } from "@rachelallyson/hero-hook-form";
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Option B: Aggregate HeroUI Package (Recommended for Development)
|
|
117
|
-
|
|
118
|
-
Install the all-in-one HeroUI package for convenience:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
npm i @rachelallyson/hero-hook-form react-hook-form @heroui/react
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Import from the `/react` subpath:
|
|
125
|
-
|
|
126
|
-
```tsx
|
|
127
|
-
import { InputField, SelectField, CheckboxField, RadioGroupField, SwitchField, TextareaField, SubmitButton } from "@rachelallyson/hero-hook-form/react";
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## Setup (recommended)
|
|
131
|
-
|
|
132
|
-
Most HeroUI apps wrap the app with the `HeroUIProvider` from `@heroui/system` and typically set up theming via `next-themes` or similar. Example (Next.js):
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
import { HeroUIProvider } from "@heroui/system";
|
|
136
|
-
import { ThemeProvider } from "next-themes";
|
|
137
|
-
|
|
138
|
-
export function Providers({ children }: { children: React.ReactNode }) {
|
|
139
|
-
return (
|
|
140
|
-
<HeroUIProvider>
|
|
141
|
-
<ThemeProvider attribute="class" defaultTheme="dark">
|
|
142
|
-
{children}
|
|
143
|
-
</ThemeProvider>
|
|
144
|
-
</HeroUIProvider>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## Global configuration (defaults)
|
|
150
|
-
|
|
151
|
-
Set global defaults for all fields with `HeroHookFormProvider`. You can set a `common` bucket (applies to all supported components) and/or per-component buckets. Per-instance props always win.
|
|
152
|
-
|
|
153
|
-
Import the provider from the entrypoint you use (root or `/react`):
|
|
154
|
-
|
|
155
|
-
```tsx
|
|
156
|
-
import { HeroHookFormProvider } from "@rachelallyson/hero-hook-form"; // or "/react"
|
|
157
|
-
|
|
158
|
-
export function AppProviders({ children }: { children: React.ReactNode }) {
|
|
159
|
-
return (
|
|
160
|
-
<HeroHookFormProvider
|
|
161
|
-
defaults={{
|
|
162
|
-
// Common keys shared across text-like controls (Input, Textarea, Select)
|
|
163
|
-
// and safely narrowed for toggles and the submit button.
|
|
164
|
-
common: {
|
|
165
|
-
color: "primary",
|
|
166
|
-
size: "md",
|
|
167
|
-
variant: "faded",
|
|
168
|
-
radius: "sm",
|
|
169
|
-
labelPlacement: "outside",
|
|
170
|
-
},
|
|
171
|
-
// Component-specific defaults override 'common' for that component
|
|
172
|
-
input: { variant: "underlined" },
|
|
173
|
-
select: { variant: "flat" },
|
|
174
|
-
submitButton: { color: "secondary" },
|
|
175
|
-
}}
|
|
176
|
-
>
|
|
177
|
-
{children}
|
|
178
|
-
</HeroHookFormProvider>
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
- Precedence (highest last):
|
|
184
|
-
1) `defaults.common`
|
|
185
|
-
2) `defaults.{component}` (e.g., `input`, `select`, `checkbox`, `radioGroup`, `switch`, `textarea`, `submitButton`)
|
|
186
|
-
3) Per-instance props (e.g., `inputProps`, `selectProps`, `checkboxProps`, etc.)
|
|
187
|
-
|
|
188
|
-
- Supported `common` keys (strongly typed and intersected across text-like controls):
|
|
189
|
-
- `color`, `size`, `variant`, `radius`, `labelPlacement`
|
|
190
|
-
- For toggles (`checkbox`, `radioGroup`, `switch`) and `submitButton`, only `color` and `size` are applied.
|
|
191
|
-
|
|
192
|
-
- Example instance override:
|
|
193
|
-
|
|
194
|
-
```tsx
|
|
195
|
-
<InputField
|
|
196
|
-
control={methods.control}
|
|
197
|
-
label="Name"
|
|
198
|
-
name="name"
|
|
199
|
-
inputProps={{ color: "danger" }} // overrides global defaults for this field
|
|
200
|
-
/>
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
- Scoping defaults: you can nest providers to scope different defaults to specific sections of your app.
|
|
204
|
-
|
|
205
|
-
## Zod Integration (Optional)
|
|
206
|
-
|
|
207
|
-
For type-safe validation with Zod schemas, install the additional dependencies:
|
|
208
|
-
|
|
209
|
-
```bash
|
|
210
|
-
npm i zod @hookform/resolvers
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Then use the `ZodForm` component with Zod schemas:
|
|
214
|
-
|
|
215
|
-
```tsx
|
|
216
|
-
import { z } from "zod";
|
|
217
|
-
import { ZodForm, createZodFormConfig } from "@rachelallyson/hero-hook-form";
|
|
218
|
-
|
|
219
|
-
// Define your schema
|
|
220
|
-
const contactSchema = z.object({
|
|
221
|
-
firstName: z.string().min(2, "First name must be at least 2 characters"),
|
|
222
|
-
email: z.string().email("Please enter a valid email address"),
|
|
223
|
-
message: z.string().min(10, "Message must be at least 10 characters"),
|
|
224
|
-
terms: z.boolean().refine((val) => val === true, "You must agree to the terms"),
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// Create form configuration
|
|
228
|
-
const config = createZodFormConfig(contactSchema, [
|
|
229
|
-
{ name: "firstName", type: "input", label: "First Name" },
|
|
230
|
-
{ name: "email", type: "input", label: "Email", inputProps: { type: "email" } },
|
|
231
|
-
{ name: "message", type: "textarea", label: "Message" },
|
|
232
|
-
{ name: "terms", type: "checkbox", label: "I agree to the terms" },
|
|
233
|
-
]);
|
|
234
|
-
|
|
235
|
-
// Use in your component
|
|
236
|
-
<ZodForm
|
|
237
|
-
config={config}
|
|
238
|
-
onSubmit={handleSubmit}
|
|
239
|
-
title="Contact Form"
|
|
240
|
-
showResetButton={true}
|
|
241
|
-
/>
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Nested Fields and Radio Buttons
|
|
245
|
-
|
|
246
|
-
For nested field names and radio buttons:
|
|
247
|
-
|
|
248
|
-
```tsx
|
|
249
|
-
const settingsSchema = z.object({
|
|
250
|
-
fonts: z.object({
|
|
251
|
-
scale: z.enum(["small", "medium", "large"]).default("medium"),
|
|
252
|
-
}),
|
|
253
|
-
layout: z.object({
|
|
254
|
-
sidebarPosition: z.enum(["left", "right", "hidden"]).default("left"),
|
|
255
|
-
}),
|
|
256
|
-
style: z.object({
|
|
257
|
-
theme: z.enum(["light", "dark", "auto"]).default("auto"),
|
|
258
|
-
}),
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
const config = createZodFormConfig(settingsSchema, [
|
|
262
|
-
{
|
|
263
|
-
name: "fonts.scale",
|
|
264
|
-
type: "radio",
|
|
265
|
-
label: "Font Scale",
|
|
266
|
-
radioOptions: [
|
|
267
|
-
{ label: "Small", value: "small" },
|
|
268
|
-
{ label: "Medium", value: "medium" },
|
|
269
|
-
{ label: "Large", value: "large" },
|
|
270
|
-
],
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
name: "layout.sidebarPosition",
|
|
274
|
-
type: "radio",
|
|
275
|
-
label: "Sidebar Position",
|
|
276
|
-
radioOptions: [
|
|
277
|
-
{ label: "Left", value: "left" },
|
|
278
|
-
{ label: "Right", value: "right" },
|
|
279
|
-
{ label: "Hidden", value: "hidden" },
|
|
280
|
-
],
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
name: "style.theme",
|
|
284
|
-
type: "radio",
|
|
285
|
-
label: "Theme",
|
|
286
|
-
radioOptions: [
|
|
287
|
-
{ label: "Light", value: "light" },
|
|
288
|
-
{ label: "Dark", value: "dark" },
|
|
289
|
-
{ label: "Auto", value: "auto" },
|
|
290
|
-
],
|
|
291
|
-
},
|
|
292
|
-
], {
|
|
293
|
-
defaultValues: {
|
|
294
|
-
fonts: { scale: "large" },
|
|
295
|
-
layout: { sidebarPosition: "right" },
|
|
296
|
-
style: { theme: "auto" },
|
|
297
|
-
},
|
|
298
|
-
});
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### Zod Features
|
|
302
|
-
|
|
303
|
-
- **Type Safety**: Full TypeScript support with automatic type inference
|
|
304
|
-
- **Nested Fields**: Support for nested field names like "fonts.scale"
|
|
305
|
-
- **Default Values**: Proper handling of default values with nested structure
|
|
306
|
-
- **Radio Buttons**: Easy configuration with `radioOptions`
|
|
307
|
-
|
|
308
|
-
## ๐ฏ Examples
|
|
309
|
-
|
|
310
|
-
Check out our [comprehensive demo](../example/app/comprehensive-demo/page.tsx) to see Hero Hook Form in action with all field types and layouts!
|
|
311
|
-
|
|
312
|
-
## ๐ Documentation
|
|
313
|
-
|
|
314
|
-
For comprehensive guides and examples, visit our [documentation](./docs/README.md):
|
|
315
|
-
|
|
316
|
-
- [๐ Getting Started](./docs/getting-started.md) - Installation, setup, and first form
|
|
317
|
-
- [๐งฉ Components](./docs/components.md) - All available field components
|
|
318
|
-
- [โ๏ธ Configuration](./docs/configuration.md) - Global configuration and providers
|
|
319
|
-
- [๐ Form Builder](./docs/form-builder.md) - ConfigurableForm component
|
|
320
|
-
- [โ
Validation](./docs/validation.md) - Form validation patterns
|
|
321
|
-
- [๐ฎ Zod Integration](./docs/zod-integration.md) - Schema-based validation with Zod
|
|
322
|
-
- [๐จ Layouts](./docs/layouts.md) - Form layout options
|
|
323
|
-
- [๐ API Reference](./docs/api-reference.md) - Complete API documentation
|
|
324
|
-
|
|
325
|
-
## ๐ง API Overview
|
|
326
|
-
|
|
327
|
-
### Field Components
|
|
328
|
-
|
|
329
|
-
All field components are strongly typed and expose component-specific props:
|
|
330
|
-
|
|
331
|
-
- **`InputField`** - Text inputs with validation
|
|
332
|
-
- **`TextareaField`** - Multi-line text inputs
|
|
333
|
-
- **`SelectField`** - Dropdown selections
|
|
334
|
-
- **`RadioGroupField`** - Radio button groups
|
|
335
|
-
- **`CheckboxField`** - Single checkboxes
|
|
336
|
-
- **`SwitchField`** - Toggle switches
|
|
337
|
-
- **`SliderField`** - Range slider inputs
|
|
338
|
-
- **`DateField`** - Date picker inputs
|
|
339
|
-
- **`FileField`** - File upload inputs
|
|
340
|
-
- **`FontPickerField`** - Optional font selection (requires `@rachelallyson/heroui-font-picker`)
|
|
341
|
-
|
|
342
|
-
### Form Components
|
|
343
|
-
|
|
344
|
-
- **`Form`** - Light wrapper around React Hook Form's FormProvider
|
|
345
|
-
- **`FormField`** - Generic field wrapper component
|
|
346
|
-
- **`ZodForm`** - Schema-based forms with Zod validation
|
|
347
|
-
- **`ConfigurableForm`** - Rapid form development with declarative config
|
|
348
|
-
|
|
349
|
-
### Utilities & Hooks
|
|
350
|
-
|
|
351
|
-
- **`applyServerErrors`** - Map API validation errors to form fields
|
|
352
|
-
- **`HeroHookFormProvider`** - Global configuration for consistent styling
|
|
353
|
-
- **`useHeroForm`** - Enhanced form hook with additional utilities
|
|
354
|
-
- **`useFormHelper`** - Form helper utilities
|
|
355
|
-
|
|
356
|
-
For complete API documentation, see [API Reference](./docs/api-reference.md).
|
|
357
|
-
|
|
358
|
-
## ๐ฏ Entrypoint Selection
|
|
359
|
-
|
|
360
|
-
- **Default entrypoint**: For apps using individual HeroUI packages (better tree-shaking)
|
|
361
|
-
- **`/react` entrypoint**: For apps using `@heroui/react` (convenient single dependency)
|
|
362
|
-
|
|
363
|
-
Both entrypoints are fully tree-shakeable and support all features.
|
|
364
|
-
|
|
365
|
-
## โ FAQ
|
|
366
|
-
|
|
367
|
-
<details>
|
|
368
|
-
<summary><strong>Do I need to wrap with HeroUIProvider?</strong></summary>
|
|
369
|
-
|
|
370
|
-
Recommended for proper styling and navigation integration. Most HeroUI apps already do this.
|
|
371
|
-
|
|
372
|
-
</details>
|
|
373
|
-
|
|
374
|
-
<details>
|
|
375
|
-
<summary><strong>Can I tree-shake?</strong></summary>
|
|
376
|
-
|
|
377
|
-
Yes! Both entrypoints are tree-shakeable. Individual packages make size more explicit, while the aggregate is convenient.
|
|
378
|
-
|
|
379
|
-
</details>
|
|
380
|
-
|
|
381
|
-
<details>
|
|
382
|
-
<summary><strong>Do I have to install all individual packages?</strong></summary>
|
|
383
|
-
|
|
384
|
-
No! Install only the components you actually render. If you don't use `RadioGroupField`, you can omit `@heroui/radio`.
|
|
385
|
-
|
|
386
|
-
</details>
|
|
387
|
-
|
|
388
|
-
<details>
|
|
389
|
-
<summary><strong>What's the difference between the two entrypoints?</strong></summary>
|
|
390
|
-
|
|
391
|
-
- **Default**: For apps using individual HeroUI packages (better tree-shaking)
|
|
392
|
-
- **/react**: For apps using the aggregate `@heroui/react` (convenient single dependency)
|
|
393
|
-
|
|
394
|
-
</details>
|
|
395
|
-
|
|
396
|
-
## ๐ค Contributing
|
|
397
|
-
|
|
398
|
-
We welcome contributions! Please see our [contributing guidelines](CONTRIBUTING.md) for details.
|
|
399
|
-
|
|
400
|
-
## ๐ License
|
|
401
|
-
|
|
402
|
-
ISC License - see [LICENSE](LICENSE) file for details.
|
|
403
|
-
|
|
404
|
-
---
|
|
405
|
-
|
|
406
|
-
<div align="center">
|
|
407
|
-
|
|
408
|
-
**Built with โค๏ธ by [Rachel Higley](https://github.com/rachelallyson)**
|
|
409
|
-
|
|
410
|
-
[Report Bug](https://github.com/rachelallyson/hero-hook-form/issues) ยท [Request Feature](https://github.com/rachelallyson/hero-hook-form/issues) ยท [View Examples](../example/app/comprehensive-demo/page.tsx)
|
|
411
|
-
|
|
412
|
-
</div>
|