@railway-ts/use-form 0.1.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 +129 -0
- package/dist/index.d.ts +828 -0
- package/dist/index.js +989 -0
- package/dist/index.js.map +1 -0
- package/package.json +92 -0
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# @railway-ts/use-form
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@railway-ts/use-form) [](https://github.com/sakobu/railway-ts-use-form/actions) [](https://opensource.org/licenses/MIT) [](https://bundlephobia.com/package/@railway-ts/use-form) [](https://www.typescriptlang.org/) [](https://codecov.io/gh/sakobu/railway-ts-use-form)
|
|
4
|
+
|
|
5
|
+
Type-safe React form hook with Railway-oriented validation.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Type inference from validation schemas
|
|
10
|
+
- Autocomplete for nested field paths
|
|
11
|
+
- Railway-oriented composable validators
|
|
12
|
+
- Native HTML element support
|
|
13
|
+
- Dual error sources (client and server)
|
|
14
|
+
- Array field helpers with type safety
|
|
15
|
+
- Four validation modes (live, blur, mount, submit)
|
|
16
|
+
- React 19 compatible
|
|
17
|
+
- Tree-shakeable ESM
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun add @railway-ts/use-form @railway-ts/pipelines react
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires React 18+ and @railway-ts/pipelines ^0.1.5
|
|
26
|
+
|
|
27
|
+
## Quick Example
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { useForm } from '@railway-ts/use-form';
|
|
31
|
+
import {
|
|
32
|
+
object,
|
|
33
|
+
string,
|
|
34
|
+
required,
|
|
35
|
+
chain,
|
|
36
|
+
nonEmpty,
|
|
37
|
+
email,
|
|
38
|
+
type InferSchemaType,
|
|
39
|
+
} from '@railway-ts/pipelines/schema';
|
|
40
|
+
|
|
41
|
+
const loginValidator = object({
|
|
42
|
+
email: required(chain(string(), nonEmpty('Email is required'), email())),
|
|
43
|
+
password: required(chain(string(), nonEmpty('Password is required'))),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
type LoginForm = InferSchemaType<typeof loginValidator>;
|
|
47
|
+
|
|
48
|
+
function LoginForm() {
|
|
49
|
+
const form = useForm<LoginForm>(loginValidator, {
|
|
50
|
+
initialValues: { email: '', password: '' },
|
|
51
|
+
onSubmit: async (values) => {
|
|
52
|
+
console.log('Login:', values);
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<form onSubmit={form.handleSubmit}>
|
|
58
|
+
<input type="email" {...form.getFieldProps('email')} />
|
|
59
|
+
{form.touched.email && form.errors.email && (
|
|
60
|
+
<span>{form.errors.email}</span>
|
|
61
|
+
)}
|
|
62
|
+
|
|
63
|
+
<input type="password" {...form.getFieldProps('password')} />
|
|
64
|
+
{form.touched.password && form.errors.password && (
|
|
65
|
+
<span>{form.errors.password}</span>
|
|
66
|
+
)}
|
|
67
|
+
|
|
68
|
+
<button type="submit" disabled={form.isSubmitting || !form.isValid}>
|
|
69
|
+
{form.isSubmitting ? 'Logging in...' : 'Log In'}
|
|
70
|
+
</button>
|
|
71
|
+
</form>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Documentation
|
|
77
|
+
|
|
78
|
+
- [Getting Started](./GETTING_STARTED.md) - Installation, setup, core concepts
|
|
79
|
+
- [Recipes](./docs/RECIPES.md) - Common patterns and use cases
|
|
80
|
+
- [Advanced](./docs/ADVANCED.md) - Complex patterns, optimization, integration
|
|
81
|
+
- [API Reference](./docs/API.md) - Complete API documentation
|
|
82
|
+
|
|
83
|
+
## Core Concepts
|
|
84
|
+
|
|
85
|
+
### Type Inference
|
|
86
|
+
|
|
87
|
+
Derive TypeScript types from validation schemas:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
const userValidator = object({
|
|
91
|
+
username: required(string()),
|
|
92
|
+
email: required(email()),
|
|
93
|
+
age: required(parseNumber()),
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
type UserForm = InferSchemaType<typeof userValidator>;
|
|
97
|
+
// { username: string; email: string; age: number; }
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Railway Validation
|
|
101
|
+
|
|
102
|
+
Composable validators that accumulate errors:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const validator = object({
|
|
106
|
+
email: required(chain(string(), nonEmpty('Required'), email())),
|
|
107
|
+
password: required(chain(string(), minLength(8))),
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Validation Modes
|
|
112
|
+
|
|
113
|
+
- `live` - Validate on change and blur, mark touched on change
|
|
114
|
+
- `blur` - Validate on blur only
|
|
115
|
+
- `mount` - Validate once on mount, mark all fields touched
|
|
116
|
+
- `submit` - Validate only on submit
|
|
117
|
+
|
|
118
|
+
## Development
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
bun install
|
|
122
|
+
bun run build
|
|
123
|
+
bun test
|
|
124
|
+
bun run example
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT © Sarkis Melkonian
|