ngx-form-stepper 0.0.10 β 0.0.12
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 +113 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[π«π· Lire la version franΓ§aise](https://github.com/rayaneriahi/ngx-form-stepper/blob/main/README.fr.md)
|
|
4
4
|
|
|
5
|
-
**ngx-form-stepper** is an Angular library to create multi-step forms with field-level
|
|
5
|
+
**ngx-form-stepper** is an Angular library that allows you to create multi-step forms with field-level validation, **extremely strongly typed**.
|
|
6
6
|
|
|
7
7
|
It prevents creating invalid states **at development time**, not at runtime.
|
|
8
8
|
|
|
@@ -62,26 +62,6 @@ onComplete() {
|
|
|
62
62
|
|
|
63
63
|
## Input
|
|
64
64
|
|
|
65
|
-
Each `Input` type only accepts compatible `validators`.
|
|
66
|
-
|
|
67
|
-
Examples :
|
|
68
|
-
|
|
69
|
-
- `email` β forbidden on `number`
|
|
70
|
-
- `minLength` β forbidden on `checkbox`
|
|
71
|
-
- `confirm` β forbidden on `select`
|
|
72
|
-
|
|
73
|
-
And only default values that are compatible.
|
|
74
|
-
|
|
75
|
-
Examples :
|
|
76
|
-
|
|
77
|
-
- `string` β forbidden on `number`
|
|
78
|
-
- `number` β forbidden on `checkbox`
|
|
79
|
-
- `string | number` β forbidden on `select`
|
|
80
|
-
|
|
81
|
-
Return key must be camelCase.
|
|
82
|
-
|
|
83
|
-
Duplicating a `validator` is impossible.
|
|
84
|
-
|
|
85
65
|
```typescript
|
|
86
66
|
export class Input<
|
|
87
67
|
T extends InputType,
|
|
@@ -116,6 +96,28 @@ export enum InputType {
|
|
|
116
96
|
}
|
|
117
97
|
```
|
|
118
98
|
|
|
99
|
+
Each `Input` type only accepts compatible default values.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
export type InputDefaultValue<T extends InputType> = T extends InputType.Text
|
|
103
|
+
? string | null
|
|
104
|
+
: T extends InputType.Password
|
|
105
|
+
? string | null
|
|
106
|
+
: T extends InputType.Email
|
|
107
|
+
? string | null
|
|
108
|
+
: T extends InputType.Number
|
|
109
|
+
? number | null
|
|
110
|
+
: T extends InputType.Tel
|
|
111
|
+
? string | null
|
|
112
|
+
: T extends InputType.Checkbox
|
|
113
|
+
? boolean | null
|
|
114
|
+
: T extends InputType.Date
|
|
115
|
+
? Date | null
|
|
116
|
+
: T extends InputType.Select
|
|
117
|
+
? Select<SelectItemTuple, number | null>
|
|
118
|
+
: never;
|
|
119
|
+
```
|
|
120
|
+
|
|
119
121
|
## Validator
|
|
120
122
|
|
|
121
123
|
A `validator` is a function that can be passed to an `Input`. It takes different arguments like conditional values or error text.
|
|
@@ -156,6 +158,52 @@ export type ValidatorsNames =
|
|
|
156
158
|
| 'maxDate';
|
|
157
159
|
```
|
|
158
160
|
|
|
161
|
+
Each `Input` type only accepts compatible validators.
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
export type ValidatorsNamesOfType<T extends InputType> = T extends InputType.Text
|
|
165
|
+
? 'required' | 'confirm' | 'minLength' | 'maxLength' | 'pattern'
|
|
166
|
+
: T extends InputType.Password
|
|
167
|
+
? 'required' | 'confirm' | 'strongPassword' | 'pattern'
|
|
168
|
+
: T extends InputType.Email
|
|
169
|
+
? 'required' | 'confirm' | 'email'
|
|
170
|
+
: T extends InputType.Number
|
|
171
|
+
? 'required' | 'confirm' | 'min' | 'max' | 'integer'
|
|
172
|
+
: T extends InputType.Tel
|
|
173
|
+
? 'required' | 'confirm' | 'phone'
|
|
174
|
+
: T extends InputType.Checkbox
|
|
175
|
+
? 'check'
|
|
176
|
+
: T extends InputType.Date
|
|
177
|
+
? 'required' | 'confirm' | 'minDate' | 'maxDate'
|
|
178
|
+
: T extends InputType.Select
|
|
179
|
+
? 'required'
|
|
180
|
+
: never;
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Reusing typed validators
|
|
184
|
+
|
|
185
|
+
**ngx-form-stepper** allows you to factor them out, then create groups of `validators` that are compatible only with a given `Input` type:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
reqVal: Validator<'required'> = required('Field is required');
|
|
189
|
+
|
|
190
|
+
emailValidators: ValidatorTuple<ValidatorsNamesOfType<InputType.Email>> = [
|
|
191
|
+
reqVal,
|
|
192
|
+
email('E-mail is not valid'),
|
|
193
|
+
];
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
What is impossible (and intentional)
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// β Compilation error
|
|
200
|
+
const badValidators: ValidatorTuple<ValidatorsNamesOfType<InputType.Number>> = [
|
|
201
|
+
email('Invalid email'),
|
|
202
|
+
];
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
This error is detected at compile time, even before running the application.
|
|
206
|
+
|
|
159
207
|
## Select
|
|
160
208
|
|
|
161
209
|
Tuple of one or more `SelectItem`.
|
|
@@ -190,9 +238,25 @@ export type SelectItem = {
|
|
|
190
238
|
};
|
|
191
239
|
```
|
|
192
240
|
|
|
193
|
-
|
|
241
|
+
Assigning an invalid currentIndex is impossible.
|
|
194
242
|
|
|
195
|
-
|
|
243
|
+
```typescript
|
|
244
|
+
// β Compilation error
|
|
245
|
+
invalid = new Input(
|
|
246
|
+
InputType.Select,
|
|
247
|
+
new Select(
|
|
248
|
+
[
|
|
249
|
+
{ label: 'Male', value: 'male' },
|
|
250
|
+
{ label: 'Female', value: 'female' },
|
|
251
|
+
],
|
|
252
|
+
5
|
|
253
|
+
),
|
|
254
|
+
'gender',
|
|
255
|
+
'Gender'
|
|
256
|
+
);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Step
|
|
196
260
|
|
|
197
261
|
Tuple of one or more `Inputs`.
|
|
198
262
|
|
|
@@ -209,12 +273,20 @@ export type StepConfig = Readonly<{
|
|
|
209
273
|
}>;
|
|
210
274
|
```
|
|
211
275
|
|
|
276
|
+
Duplication of `returnKey` is forbidden (and intentional)
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
// β Compilation error
|
|
280
|
+
new Step([
|
|
281
|
+
new Input(InputType.Text, null, 'name', 'First name'),
|
|
282
|
+
new Input(InputType.Text, null, 'name', 'Last name'),
|
|
283
|
+
]);
|
|
284
|
+
```
|
|
285
|
+
|
|
212
286
|
## FormStepper
|
|
213
287
|
|
|
214
288
|
Impossible to duplicate an `Input` return key between two `Steps`.
|
|
215
289
|
|
|
216
|
-
Configuration object depending on the number of `Steps`.
|
|
217
|
-
|
|
218
290
|
Tuple of one or more `Steps`.
|
|
219
291
|
|
|
220
292
|
```typescript
|
|
@@ -230,7 +302,11 @@ export class FormStepper<T extends StepTuple> {
|
|
|
230
302
|
) as FormStepperValues<T>;
|
|
231
303
|
}
|
|
232
304
|
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Configuration object depending on the number of `Steps`.
|
|
233
308
|
|
|
309
|
+
```typescript
|
|
234
310
|
export type SingleStepConfig = Readonly<{
|
|
235
311
|
title?: string;
|
|
236
312
|
actionText?: RedirectItem[];
|
|
@@ -253,7 +329,7 @@ export type MultiStepConfig = Readonly<{
|
|
|
253
329
|
A `RedirectItem[]` is an array of strings or `RedirectUrl` objects, a kind of mini TS language to create texts with clickable links.
|
|
254
330
|
|
|
255
331
|
```typescript
|
|
256
|
-
actionText = ['You already have an account
|
|
332
|
+
actionText = ['You already have an account?', { url: '/signin', urlText: 'Sign in' }];
|
|
257
333
|
|
|
258
334
|
export type RedirectUrl = Readonly<{ url: string; urlText: string }>;
|
|
259
335
|
|
|
@@ -288,7 +364,10 @@ classNames: SingleStepClassNames = {
|
|
|
288
364
|
},
|
|
289
365
|
};
|
|
290
366
|
|
|
291
|
-
form = new FormStepper([this.step], {
|
|
367
|
+
form = new FormStepper([this.step], {
|
|
368
|
+
buttonText: 'Submit',
|
|
369
|
+
classNames: this.classNames,
|
|
370
|
+
});
|
|
292
371
|
```
|
|
293
372
|
|
|
294
373
|
```css
|
|
@@ -384,3 +463,10 @@ export type MultiStepClassNames = DeepPartial<{
|
|
|
384
463
|
};
|
|
385
464
|
}>;
|
|
386
465
|
```
|
|
466
|
+
|
|
467
|
+
## In summary
|
|
468
|
+
|
|
469
|
+
- Common errors are impossible
|
|
470
|
+
- Types guide the implementation
|
|
471
|
+
- The final form is always consistent
|
|
472
|
+
- The compiler becomes an ally
|