ngx-form-stepper 0.0.1

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.
@@ -0,0 +1,733 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, Injectable, inject, computed, Component, input, viewChild, effect, output } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i2 from '@angular/forms';
6
+ import { FormGroup, FormControl, FormGroupDirective, ControlContainer, ReactiveFormsModule } from '@angular/forms';
7
+ import { RouterLink } from '@angular/router';
8
+
9
+ class FormStepper {
10
+ steps;
11
+ config;
12
+ values;
13
+ constructor(steps, config) {
14
+ this.steps = steps;
15
+ this.config = config;
16
+ this.values = Object.fromEntries(steps.flatMap((step) => step.inputs.map((input) => [input.returnKey, input.defaultValue])));
17
+ }
18
+ }
19
+
20
+ var InputType;
21
+ (function (InputType) {
22
+ InputType["Text"] = "text";
23
+ InputType["Password"] = "password";
24
+ InputType["Email"] = "email";
25
+ InputType["Number"] = "number";
26
+ InputType["Tel"] = "tel";
27
+ InputType["Checkbox"] = "checkbox";
28
+ InputType["Date"] = "date";
29
+ InputType["Select"] = "select";
30
+ })(InputType || (InputType = {}));
31
+
32
+ class FormStepperService {
33
+ formStepper = signal(null, ...(ngDevMode ? [{ debugName: "formStepper" }] : []));
34
+ stepsForm = signal(null, ...(ngDevMode ? [{ debugName: "stepsForm" }] : []));
35
+ index = signal(0, ...(ngDevMode ? [{ debugName: "index" }] : []));
36
+ completed = signal(false, ...(ngDevMode ? [{ debugName: "completed" }] : []));
37
+ setFormStepper(formStepper) {
38
+ this.formStepper.update(() => formStepper);
39
+ this.setStepsForm();
40
+ }
41
+ dateToInputFormat(date) {
42
+ const year = date.getFullYear();
43
+ const month = (date.getMonth() + 1).toString().padStart(2, "0");
44
+ const day = date.getDate().toString().padStart(2, "0");
45
+ return `${year}-${month}-${day}`;
46
+ }
47
+ setStepsForm() {
48
+ const steps = this.formStepper()?.steps ?? null;
49
+ if (steps === null)
50
+ return;
51
+ const forms = Object.fromEntries(steps.map((step, index) => {
52
+ const validators = step.inputs.flatMap((i) => {
53
+ const cv = i.validators
54
+ ? i.validators.find((v) => v.kind === "confirm") ?? null
55
+ : null;
56
+ if (cv === null)
57
+ return [];
58
+ return cv.fn({
59
+ key: i.returnKey,
60
+ confirmKey: this.getConfirmReturnKey(i.returnKey),
61
+ });
62
+ });
63
+ return [
64
+ index,
65
+ new FormGroup(Object.fromEntries(step.inputs.flatMap((input) => {
66
+ const confirm = input.validators
67
+ ? input.validators.find((v) => v.kind === "confirm") ?? null
68
+ : null;
69
+ const other = input.validators
70
+ ? input.validators.filter((v) => v.kind !== "confirm")
71
+ : [];
72
+ const validators = [];
73
+ other.forEach((v) => {
74
+ validators.push(v.fn({ key: input.returnKey }));
75
+ });
76
+ const defaultValue = input.defaultValue === null
77
+ ? input.type === InputType.Checkbox
78
+ ? "false"
79
+ : ""
80
+ : input.type === InputType.Number
81
+ ? Number.isNaN(input.defaultValue)
82
+ ? ""
83
+ : `${input.defaultValue}`
84
+ : input.type === InputType.Checkbox
85
+ ? `${input.defaultValue}`
86
+ : input.type === InputType.Date
87
+ ? this.dateToInputFormat(input.defaultValue)
88
+ : input.type === InputType.Select
89
+ ? input.defaultValue.current === null
90
+ ? ""
91
+ : input.defaultValue.current.value
92
+ : input.defaultValue;
93
+ const controls = [
94
+ [
95
+ input.returnKey,
96
+ new FormControl(defaultValue, validators),
97
+ ],
98
+ ];
99
+ if (confirm !== null) {
100
+ controls.push([
101
+ this.getConfirmReturnKey(input.returnKey),
102
+ new FormControl(defaultValue),
103
+ ]);
104
+ }
105
+ return controls;
106
+ })), { validators }),
107
+ ];
108
+ }));
109
+ this.stepsForm.update(() => forms);
110
+ }
111
+ getConfirmReturnKey(returnKey) {
112
+ return `confirm-${returnKey}`;
113
+ }
114
+ updateValues(values) {
115
+ const fs = this.formStepper();
116
+ const step = this.formStepper()?.steps[this.index()] ?? null;
117
+ if (fs === null || step === null)
118
+ return;
119
+ Object.entries(values).forEach(([key, value]) => {
120
+ const type = step.inputs.find((input) => input.returnKey === key)?.type;
121
+ if (type === undefined)
122
+ return;
123
+ fs.values[key] =
124
+ type === InputType.Checkbox
125
+ ? value === "true"
126
+ : value === ""
127
+ ? null
128
+ : type === InputType.Number
129
+ ? Number.isNaN(Number(value))
130
+ ? null
131
+ : Number(value)
132
+ : type === InputType.Tel
133
+ ? value.replace(/\s|-/g, "")
134
+ : type === InputType.Date
135
+ ? new Date(value)
136
+ : value;
137
+ });
138
+ step.inputs.forEach((input) => {
139
+ const confirm = input.validators
140
+ ? input.validators.find((v) => v.kind === "confirm") ?? null
141
+ : null;
142
+ if (confirm !== null) {
143
+ const confirmKey = this.getConfirmReturnKey(input.returnKey);
144
+ delete fs.values[confirmKey];
145
+ }
146
+ });
147
+ }
148
+ next() {
149
+ const index = this.index();
150
+ const length = this.formStepper()?.steps.length ?? null;
151
+ if (length === null)
152
+ return;
153
+ if (index < length - 1) {
154
+ this.index.update((index) => index + 1);
155
+ }
156
+ else {
157
+ this.complete();
158
+ }
159
+ }
160
+ previous() {
161
+ const index = this.index();
162
+ if (index > 0) {
163
+ this.index.update((index) => index - 1);
164
+ }
165
+ }
166
+ complete() {
167
+ this.completed.update(() => true);
168
+ }
169
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormStepperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
170
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormStepperService });
171
+ }
172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormStepperService, decorators: [{
173
+ type: Injectable
174
+ }] });
175
+
176
+ class StepService {
177
+ service = inject(FormStepperService);
178
+ step = computed(() => this.service.formStepper()?.steps[this.service.index()] ?? null, ...(ngDevMode ? [{ debugName: "step" }] : []));
179
+ classNames = computed(() => this.service.formStepper()?.config.classNames?.step, ...(ngDevMode ? [{ debugName: "classNames" }] : []));
180
+ form = computed(() => this.service.stepsForm()?.[this.service.index()] ?? null, ...(ngDevMode ? [{ debugName: "form" }] : []));
181
+ onSubmit() {
182
+ const form = this.form();
183
+ if (form === null)
184
+ return;
185
+ const values = form.getRawValue();
186
+ this.service.updateValues(values);
187
+ this.service.next();
188
+ }
189
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: StepService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
190
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: StepService });
191
+ }
192
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: StepService, decorators: [{
193
+ type: Injectable
194
+ }] });
195
+
196
+ class ButtonService {
197
+ service = inject(FormStepperService);
198
+ text = computed(() => this.service.formStepper()?.config.buttonText ?? null, ...(ngDevMode ? [{ debugName: "text" }] : []));
199
+ classNames = computed(() => this.service.formStepper()?.config.classNames?.button, ...(ngDevMode ? [{ debugName: "classNames" }] : []));
200
+ form = computed(() => this.service.stepsForm()?.[this.service.index()] ?? null, ...(ngDevMode ? [{ debugName: "form" }] : []));
201
+ view = computed(() => {
202
+ const type = this.service.formStepper()?.steps.length === 1 ? 'single' : 'multi';
203
+ const text = this.text();
204
+ const classNames = this.classNames();
205
+ if (type === null || text === null)
206
+ return null;
207
+ if (type === 'single') {
208
+ return {
209
+ kind: 'single',
210
+ text: text,
211
+ classNames: classNames,
212
+ };
213
+ }
214
+ return {
215
+ kind: 'multi',
216
+ text: text,
217
+ classNames: classNames,
218
+ };
219
+ }, ...(ngDevMode ? [{ debugName: "view" }] : []));
220
+ stepPosition = computed(() => {
221
+ const fs = this.service.formStepper();
222
+ if (fs === null)
223
+ return null;
224
+ const length = fs.steps.length - 1;
225
+ const index = this.service.index();
226
+ return index === 0
227
+ ? 'first'
228
+ : index === length
229
+ ? 'last'
230
+ : 'middle';
231
+ }, ...(ngDevMode ? [{ debugName: "stepPosition" }] : []));
232
+ previous() {
233
+ this.service.previous();
234
+ }
235
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
236
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonService });
237
+ }
238
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonService, decorators: [{
239
+ type: Injectable
240
+ }] });
241
+
242
+ class ButtonComponent {
243
+ service = inject(ButtonService);
244
+ form = this.service.form;
245
+ view = this.service.view;
246
+ stepPosition = this.service.stepPosition;
247
+ previous() {
248
+ this.service.previous();
249
+ }
250
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
251
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ButtonComponent, isStandalone: true, selector: "app-button", providers: [ButtonService], ngImport: i0, template: "@let _view = view(); @let _form = form(); @let _stepPosition = stepPosition(); @if (_view !== null\r\n&& _form !== null && _view.kind === 'single') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text }}\r\n </button>\r\n</div>\r\n} @if (_view !== null && _form !== null && _view.kind === 'multi' && _stepPosition === 'first') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.first ?? '',\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text?.next }}\r\n </button>\r\n</div>\r\n} @if (_view !== null && _form !== null && _view.kind === 'multi' && _stepPosition === 'middle') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n (click)=\"previous()\"\r\n [ngClass]=\"[_view.classNames?.previous ?? '', _view.classNames?.button ?? '']\"\r\n type=\"button\"\r\n >\r\n {{ _view.text?.previous }}\r\n </button>\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.next ?? '',\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text?.next }}\r\n </button>\r\n</div>\r\n} @if (_view !== null && _form !== null && _view.kind === 'multi' && _stepPosition === 'last') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n (click)=\"previous()\"\r\n [ngClass]=\"[_view.classNames?.previous ?? '', _view.classNames?.button ?? '']\"\r\n type=\"button\"\r\n >\r\n {{ _view.text?.previous }}\r\n </button>\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.final ?? '',\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text?.final }}\r\n </button>\r\n</div>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
252
+ }
253
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonComponent, decorators: [{
254
+ type: Component,
255
+ args: [{ selector: 'app-button', imports: [CommonModule], providers: [ButtonService], template: "@let _view = view(); @let _form = form(); @let _stepPosition = stepPosition(); @if (_view !== null\r\n&& _form !== null && _view.kind === 'single') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text }}\r\n </button>\r\n</div>\r\n} @if (_view !== null && _form !== null && _view.kind === 'multi' && _stepPosition === 'first') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.first ?? '',\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text?.next }}\r\n </button>\r\n</div>\r\n} @if (_view !== null && _form !== null && _view.kind === 'multi' && _stepPosition === 'middle') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n (click)=\"previous()\"\r\n [ngClass]=\"[_view.classNames?.previous ?? '', _view.classNames?.button ?? '']\"\r\n type=\"button\"\r\n >\r\n {{ _view.text?.previous }}\r\n </button>\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.next ?? '',\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text?.next }}\r\n </button>\r\n</div>\r\n} @if (_view !== null && _form !== null && _view.kind === 'multi' && _stepPosition === 'last') {\r\n<div [ngClass]=\"_view.classNames?.container ?? ''\">\r\n <button\r\n (click)=\"previous()\"\r\n [ngClass]=\"[_view.classNames?.previous ?? '', _view.classNames?.button ?? '']\"\r\n type=\"button\"\r\n >\r\n {{ _view.text?.previous }}\r\n </button>\r\n <button\r\n [ngClass]=\"[\r\n _view.classNames?.final ?? '',\r\n _view.classNames?.button ?? '',\r\n _form.invalid ? _view.classNames?.disabled ?? '' : ''\r\n ]\"\r\n type=\"submit\"\r\n >\r\n {{ _view.text?.final }}\r\n </button>\r\n</div>\r\n}\r\n" }]
256
+ }] });
257
+
258
+ class InputService {
259
+ service = inject(FormStepperService);
260
+ key = signal(null, ...(ngDevMode ? [{ debugName: "key" }] : []));
261
+ confirmKey = computed(() => {
262
+ const key = this.key();
263
+ if (key === null)
264
+ return null;
265
+ return this.service.getConfirmReturnKey(key);
266
+ }, ...(ngDevMode ? [{ debugName: "confirmKey" }] : []));
267
+ classNames = computed(() => this.service.formStepper()?.config.classNames?.input, ...(ngDevMode ? [{ debugName: "classNames" }] : []));
268
+ input = computed(() => this.service
269
+ .formStepper()
270
+ ?.steps[this.service.index()]?.inputs.find((input) => input.returnKey === this.key()) ??
271
+ null, ...(ngDevMode ? [{ debugName: "input" }] : []));
272
+ confirmValidator = computed(() => this.input()?.validators?.find((v) => v.kind === 'confirm') ?? null, ...(ngDevMode ? [{ debugName: "confirmValidator" }] : []));
273
+ othersValidators = computed(() => this.input()?.validators?.filter((v) => v.kind !== 'confirm') ?? null, ...(ngDevMode ? [{ debugName: "othersValidators" }] : []));
274
+ form = computed(() => this.service.stepsForm()?.[this.service.index()] ?? null, ...(ngDevMode ? [{ debugName: "form" }] : []));
275
+ control = computed(() => {
276
+ const key = this.key();
277
+ if (key === null)
278
+ return null;
279
+ return this.form()?.get(key) ?? null;
280
+ }, ...(ngDevMode ? [{ debugName: "control" }] : []));
281
+ confirmControl = computed(() => {
282
+ const confirmKey = this.confirmKey();
283
+ if (confirmKey === null)
284
+ return null;
285
+ return this.form()?.get(confirmKey) ?? null;
286
+ }, ...(ngDevMode ? [{ debugName: "confirmControl" }] : []));
287
+ inputContainerCn = computed(() => this.service.formStepper()?.config.classNames?.step?.inputContainer, ...(ngDevMode ? [{ debugName: "inputContainerCn" }] : []));
288
+ isRequired = computed(() => {
289
+ const othersValidators = this.othersValidators();
290
+ if (othersValidators === null)
291
+ return false;
292
+ return othersValidators.some((v) => v.kind === 'required');
293
+ }, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
294
+ selectItems = computed(() => {
295
+ const input = this.input();
296
+ if (input === null || input.type !== InputType.Select)
297
+ return null;
298
+ return input.defaultValue.items;
299
+ }, ...(ngDevMode ? [{ debugName: "selectItems" }] : []));
300
+ inputElement = signal(null, ...(ngDevMode ? [{ debugName: "inputElement" }] : []));
301
+ currentValue = null;
302
+ isCheckbox = false;
303
+ setKey(key) {
304
+ this.key.set(key);
305
+ }
306
+ setInputElement(element) {
307
+ this.inputElement.set(element);
308
+ }
309
+ verifyCheckbox() {
310
+ const control = this.control();
311
+ const element = this.inputElement();
312
+ if (control === null || element === null || !this.isCheckbox)
313
+ return;
314
+ this.currentValue = !this.currentValue;
315
+ element.checked = this.currentValue;
316
+ control.setValue(this.currentValue);
317
+ }
318
+ firstVerifyCheckbox() {
319
+ const input = this.input();
320
+ const element = this.inputElement();
321
+ const control = this.control();
322
+ if (input === null || element === null || control === null || input.type !== InputType.Checkbox)
323
+ return;
324
+ this.isCheckbox = true;
325
+ this.currentValue =
326
+ input.defaultValue === null
327
+ ? false
328
+ : input.defaultValue === false
329
+ ? false
330
+ : true;
331
+ element.checked = this.currentValue;
332
+ }
333
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
334
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputService });
335
+ }
336
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputService, decorators: [{
337
+ type: Injectable
338
+ }] });
339
+
340
+ class InputComponent {
341
+ service = inject(InputService);
342
+ key = input.required();
343
+ inputElement = viewChild('input', ...(ngDevMode ? [{ debugName: "inputElement" }] : []));
344
+ confirmKey = this.service.confirmKey;
345
+ classNames = this.service.classNames;
346
+ input = this.service.input;
347
+ confirmValidator = this.service.confirmValidator;
348
+ othersValidators = this.service.othersValidators;
349
+ form = this.service.form;
350
+ control = this.service.control;
351
+ confirmControl = this.service.confirmControl;
352
+ inputContainerCn = this.service.inputContainerCn;
353
+ isRequired = this.service.isRequired;
354
+ selectItems = this.service.selectItems;
355
+ constructor() {
356
+ effect(() => this.service.setKey(this.key()));
357
+ effect(() => {
358
+ const inputElement = this.inputElement();
359
+ if (inputElement === undefined)
360
+ return;
361
+ this.service.setInputElement(inputElement.nativeElement);
362
+ });
363
+ effect(() => this.service.firstVerifyCheckbox());
364
+ }
365
+ handleClick() {
366
+ this.service.verifyCheckbox();
367
+ }
368
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
369
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: InputComponent, isStandalone: true, selector: "app-input", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, providers: [InputService], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "@let _key = key(); @let _confirmKey = confirmKey(); @let _classNames = classNames(); @let _input =\r\ninput(); @let _confirmValidator = confirmValidator(); @let _othersValidators = othersValidators();\r\n@let _control = control(); @let _confirmControl = confirmControl(); @let _form = form(); @let\r\n_inputContainerCn = inputContainerCn(); @let _isRequired = isRequired(); @let _selectItems =\r\nselectItems(); @if (_input !== null && _confirmValidator === null) {\r\n<div [ngClass]=\"_classNames?.container ?? ''\">\r\n <label [for]=\"_key\" [ngClass]=\"_classNames?.label ?? ''\"\r\n >{{ _input.label }}\r\n @if (_isRequired) {\r\n <span [ngClass]=\"_classNames?.required ?? ''\">*</span>\r\n }\r\n </label>\r\n\r\n @if (_input.type === 'select') {\r\n <select [id]=\"_key\" [formControlName]=\"_key\" [ngClass]=\"_classNames?.input ?? ''\">\r\n @for (item of _selectItems; track item) {\r\n <option [value]=\"item.value\">\r\n {{ item.label }}\r\n </option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n #input\r\n [id]=\"_key\"\r\n [type]=\"_input.type\"\r\n (click)=\"handleClick()\"\r\n [formControlName]=\"_key\"\r\n [ngClass]=\"_classNames?.input ?? ''\"\r\n />\r\n } @if (_othersValidators !== null && _control !== null) {\r\n <div [ngClass]=\"_classNames?.errorContainer ?? ''\">\r\n @for (v of _othersValidators; track v) { @if (_control.hasError(v.name({ key: _key })) &&\r\n _control.touched) {\r\n <p [ngClass]=\"_classNames?.error ?? ''\">\r\n {{ v.errorText }}\r\n </p>\r\n } }\r\n </div>\r\n }\r\n</div>\r\n} @if (_input !== null && _confirmValidator !== null && _input.type !== 'select') {\r\n<div [ngClass]=\"_inputContainerCn ?? ''\">\r\n <div [ngClass]=\"_classNames?.container ?? ''\">\r\n <label [for]=\"_key\" [ngClass]=\"_classNames?.label ?? ''\"\r\n >{{ _input.label }}\r\n @if (_isRequired) {\r\n <span [ngClass]=\"_classNames?.required ?? ''\">*</span>\r\n }\r\n </label>\r\n\r\n <input\r\n [id]=\"_key\"\r\n [type]=\"_input.type\"\r\n [formControlName]=\"_key\"\r\n [ngClass]=\"_classNames?.input ?? ''\"\r\n />\r\n\r\n @if (_othersValidators !== null && _control !== null) {\r\n <div [ngClass]=\"_classNames?.errorContainer ?? ''\">\r\n @for (v of _othersValidators; track v) { @if (_control.hasError(v.name({ key: _key })) &&\r\n _control.touched) {\r\n <p [ngClass]=\"_classNames?.error ?? ''\">\r\n {{ v.errorText }}\r\n </p>\r\n } }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div [ngClass]=\"_classNames?.container ?? ''\">\r\n <label [for]=\"_confirmKey\" [ngClass]=\"_classNames?.label ?? ''\"\r\n >{{ _confirmValidator.confirmLabel }}\r\n @if (_isRequired) {\r\n <span [ngClass]=\"_classNames?.required ?? ''\">*</span>\r\n }\r\n </label>\r\n\r\n <input\r\n [id]=\"_confirmKey\"\r\n [type]=\"_input.type\"\r\n [formControlName]=\"_confirmKey\"\r\n [ngClass]=\"_classNames?.input ?? ''\"\r\n />\r\n\r\n @if ( _form !== null && _confirmControl !== null && _form.hasError(_confirmValidator.name({ key:\r\n _key })) && _confirmControl.touched ) {\r\n <div [ngClass]=\"_classNames?.errorContainer ?? ''\">\r\n <p [ngClass]=\"_classNames?.error ?? ''\">\r\n {{ _confirmValidator.errorText }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
370
+ {
371
+ provide: ControlContainer,
372
+ useExisting: FormGroupDirective,
373
+ },
374
+ ] });
375
+ }
376
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputComponent, decorators: [{
377
+ type: Component,
378
+ args: [{ selector: 'app-input', imports: [CommonModule, ReactiveFormsModule], providers: [InputService], viewProviders: [
379
+ {
380
+ provide: ControlContainer,
381
+ useExisting: FormGroupDirective,
382
+ },
383
+ ], template: "@let _key = key(); @let _confirmKey = confirmKey(); @let _classNames = classNames(); @let _input =\r\ninput(); @let _confirmValidator = confirmValidator(); @let _othersValidators = othersValidators();\r\n@let _control = control(); @let _confirmControl = confirmControl(); @let _form = form(); @let\r\n_inputContainerCn = inputContainerCn(); @let _isRequired = isRequired(); @let _selectItems =\r\nselectItems(); @if (_input !== null && _confirmValidator === null) {\r\n<div [ngClass]=\"_classNames?.container ?? ''\">\r\n <label [for]=\"_key\" [ngClass]=\"_classNames?.label ?? ''\"\r\n >{{ _input.label }}\r\n @if (_isRequired) {\r\n <span [ngClass]=\"_classNames?.required ?? ''\">*</span>\r\n }\r\n </label>\r\n\r\n @if (_input.type === 'select') {\r\n <select [id]=\"_key\" [formControlName]=\"_key\" [ngClass]=\"_classNames?.input ?? ''\">\r\n @for (item of _selectItems; track item) {\r\n <option [value]=\"item.value\">\r\n {{ item.label }}\r\n </option>\r\n }\r\n </select>\r\n } @else {\r\n <input\r\n #input\r\n [id]=\"_key\"\r\n [type]=\"_input.type\"\r\n (click)=\"handleClick()\"\r\n [formControlName]=\"_key\"\r\n [ngClass]=\"_classNames?.input ?? ''\"\r\n />\r\n } @if (_othersValidators !== null && _control !== null) {\r\n <div [ngClass]=\"_classNames?.errorContainer ?? ''\">\r\n @for (v of _othersValidators; track v) { @if (_control.hasError(v.name({ key: _key })) &&\r\n _control.touched) {\r\n <p [ngClass]=\"_classNames?.error ?? ''\">\r\n {{ v.errorText }}\r\n </p>\r\n } }\r\n </div>\r\n }\r\n</div>\r\n} @if (_input !== null && _confirmValidator !== null && _input.type !== 'select') {\r\n<div [ngClass]=\"_inputContainerCn ?? ''\">\r\n <div [ngClass]=\"_classNames?.container ?? ''\">\r\n <label [for]=\"_key\" [ngClass]=\"_classNames?.label ?? ''\"\r\n >{{ _input.label }}\r\n @if (_isRequired) {\r\n <span [ngClass]=\"_classNames?.required ?? ''\">*</span>\r\n }\r\n </label>\r\n\r\n <input\r\n [id]=\"_key\"\r\n [type]=\"_input.type\"\r\n [formControlName]=\"_key\"\r\n [ngClass]=\"_classNames?.input ?? ''\"\r\n />\r\n\r\n @if (_othersValidators !== null && _control !== null) {\r\n <div [ngClass]=\"_classNames?.errorContainer ?? ''\">\r\n @for (v of _othersValidators; track v) { @if (_control.hasError(v.name({ key: _key })) &&\r\n _control.touched) {\r\n <p [ngClass]=\"_classNames?.error ?? ''\">\r\n {{ v.errorText }}\r\n </p>\r\n } }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div [ngClass]=\"_classNames?.container ?? ''\">\r\n <label [for]=\"_confirmKey\" [ngClass]=\"_classNames?.label ?? ''\"\r\n >{{ _confirmValidator.confirmLabel }}\r\n @if (_isRequired) {\r\n <span [ngClass]=\"_classNames?.required ?? ''\">*</span>\r\n }\r\n </label>\r\n\r\n <input\r\n [id]=\"_confirmKey\"\r\n [type]=\"_input.type\"\r\n [formControlName]=\"_confirmKey\"\r\n [ngClass]=\"_classNames?.input ?? ''\"\r\n />\r\n\r\n @if ( _form !== null && _confirmControl !== null && _form.hasError(_confirmValidator.name({ key:\r\n _key })) && _confirmControl.touched ) {\r\n <div [ngClass]=\"_classNames?.errorContainer ?? ''\">\r\n <p [ngClass]=\"_classNames?.error ?? ''\">\r\n {{ _confirmValidator.errorText }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n}\r\n" }]
384
+ }], ctorParameters: () => [], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], inputElement: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
385
+
386
+ class StepComponent {
387
+ service = inject(StepService);
388
+ step = this.service.step;
389
+ classNames = this.service.classNames;
390
+ form = this.service.form;
391
+ onSubmit() {
392
+ const form = this.form();
393
+ if (form === null)
394
+ return;
395
+ form.invalid ? form.markAllAsTouched() : this.service.onSubmit();
396
+ }
397
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: StepComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
398
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: StepComponent, isStandalone: true, selector: "app-step", providers: [StepService], ngImport: i0, template: "@let _step = step();\r\n@let _classNames = classNames();\r\n@let _form = form();\r\n\r\n@if (_step !== null && _form !== null) {\r\n <div [ngClass]=\"_classNames?.container\">\r\n @if (_step.config?.title) {\r\n <h2 [ngClass]=\"_classNames?.title\">{{ _step.config?.title }}</h2>\r\n }\r\n\r\n <form [formGroup]=\"_form\" [ngClass]=\"_classNames?.form\" (ngSubmit)=\"onSubmit()\">\r\n <div [ngClass]=\"_classNames?.inputContainer\">\r\n @for (input of _step.inputs; track input.returnKey) {\r\n <app-input [key]=\"input.returnKey\" />\r\n }\r\n </div>\r\n\r\n <app-button />\r\n </form>\r\n </div>\r\n}\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ButtonComponent, selector: "app-button" }, { kind: "component", type: InputComponent, selector: "app-input", inputs: ["key"] }] });
399
+ }
400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: StepComponent, decorators: [{
401
+ type: Component,
402
+ args: [{ selector: 'app-step', imports: [CommonModule, ReactiveFormsModule, ButtonComponent, InputComponent], providers: [StepService], template: "@let _step = step();\r\n@let _classNames = classNames();\r\n@let _form = form();\r\n\r\n@if (_step !== null && _form !== null) {\r\n <div [ngClass]=\"_classNames?.container\">\r\n @if (_step.config?.title) {\r\n <h2 [ngClass]=\"_classNames?.title\">{{ _step.config?.title }}</h2>\r\n }\r\n\r\n <form [formGroup]=\"_form\" [ngClass]=\"_classNames?.form\" (ngSubmit)=\"onSubmit()\">\r\n <div [ngClass]=\"_classNames?.inputContainer\">\r\n @for (input of _step.inputs; track input.returnKey) {\r\n <app-input [key]=\"input.returnKey\" />\r\n }\r\n </div>\r\n\r\n <app-button />\r\n </form>\r\n </div>\r\n}\r\n" }]
403
+ }] });
404
+
405
+ class RedirectService {
406
+ service = inject(FormStepperService);
407
+ key = signal(null, ...(ngDevMode ? [{ debugName: "key" }] : []));
408
+ classNames = computed(() => {
409
+ const key = this.key();
410
+ if (key === null)
411
+ return null;
412
+ return this.service.formStepper()?.config.classNames?.[key];
413
+ }, ...(ngDevMode ? [{ debugName: "classNames" }] : []));
414
+ redirectItems = computed(() => {
415
+ const key = this.key();
416
+ if (key === null)
417
+ return null;
418
+ return this.service.formStepper()?.config[key] ?? null;
419
+ }, ...(ngDevMode ? [{ debugName: "redirectItems" }] : []));
420
+ isUrl(item) {
421
+ return typeof item === 'object' && 'url' in item && 'urlText' in item;
422
+ }
423
+ isText(item) {
424
+ return typeof item === 'string';
425
+ }
426
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RedirectService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
427
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RedirectService });
428
+ }
429
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RedirectService, decorators: [{
430
+ type: Injectable
431
+ }] });
432
+
433
+ class RedirectComponent {
434
+ service = inject(RedirectService);
435
+ key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
436
+ classNames = this.service.classNames;
437
+ redirectItems = this.service.redirectItems;
438
+ constructor() {
439
+ effect(() => this.service.key.set(this.key()));
440
+ }
441
+ isUrl(item) {
442
+ return this.service.isUrl(item);
443
+ }
444
+ isText(item) {
445
+ return this.service.isText(item);
446
+ }
447
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RedirectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
448
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RedirectComponent, isStandalone: true, selector: "app-redirect", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, providers: [RedirectService], ngImport: i0, template: "@let _classNames = classNames();\r\n@let _redirectItems = redirectItems();\r\n\r\n<p [ngClass]=\"_classNames?.container\">\r\n @for (item of _redirectItems; track item) {\r\n @if (isUrl(item)) {\r\n <a [ngClass]=\"_classNames?.url\" [routerLink]=\"item.url\">\r\n {{ item.urlText }}\r\n </a>\r\n }\r\n\r\n @if (isText(item)) {\r\n <span [ngClass]=\"_classNames?.text\">{{ item }}</span>\r\n }\r\n }\r\n</p>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
449
+ }
450
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RedirectComponent, decorators: [{
451
+ type: Component,
452
+ args: [{ selector: 'app-redirect', imports: [CommonModule, RouterLink], providers: [RedirectService], template: "@let _classNames = classNames();\r\n@let _redirectItems = redirectItems();\r\n\r\n<p [ngClass]=\"_classNames?.container\">\r\n @for (item of _redirectItems; track item) {\r\n @if (isUrl(item)) {\r\n <a [ngClass]=\"_classNames?.url\" [routerLink]=\"item.url\">\r\n {{ item.urlText }}\r\n </a>\r\n }\r\n\r\n @if (isText(item)) {\r\n <span [ngClass]=\"_classNames?.text\">{{ item }}</span>\r\n }\r\n }\r\n</p>\r\n" }]
453
+ }], ctorParameters: () => [], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }] } });
454
+
455
+ class FormStepperComponent {
456
+ service = inject(FormStepperService);
457
+ formStepper = input.required(...(ngDevMode ? [{ debugName: "formStepper" }] : []));
458
+ completed = output();
459
+ constructor() {
460
+ effect(() => {
461
+ this.service.setFormStepper(this.formStepper());
462
+ });
463
+ effect(() => {
464
+ if (this.service.completed()) {
465
+ this.completed.emit();
466
+ }
467
+ });
468
+ }
469
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
470
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: FormStepperComponent, isStandalone: true, selector: "app-form-stepper", inputs: { formStepper: { classPropertyName: "formStepper", publicName: "formStepper", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { completed: "completed" }, providers: [FormStepperService], ngImport: i0, template: "@let _formStepper = formStepper();\r\n@let classNames = _formStepper.config.classNames;\r\n\r\n<div [ngClass]=\"classNames?.container\">\r\n @if (_formStepper.config.title) {\r\n <h1 [ngClass]=\"classNames?.title\">{{ _formStepper.config.title }}</h1>\r\n }\r\n\r\n <app-redirect [key]=\"'actionText'\" />\r\n\r\n <app-step />\r\n\r\n <app-redirect [key]=\"'footerText'\" />\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: StepComponent, selector: "app-step" }, { kind: "component", type: RedirectComponent, selector: "app-redirect", inputs: ["key"] }] });
471
+ }
472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormStepperComponent, decorators: [{
473
+ type: Component,
474
+ args: [{ selector: 'app-form-stepper', imports: [CommonModule, StepComponent, RedirectComponent], providers: [FormStepperService], template: "@let _formStepper = formStepper();\r\n@let classNames = _formStepper.config.classNames;\r\n\r\n<div [ngClass]=\"classNames?.container\">\r\n @if (_formStepper.config.title) {\r\n <h1 [ngClass]=\"classNames?.title\">{{ _formStepper.config.title }}</h1>\r\n }\r\n\r\n <app-redirect [key]=\"'actionText'\" />\r\n\r\n <app-step />\r\n\r\n <app-redirect [key]=\"'footerText'\" />\r\n</div>\r\n" }]
475
+ }], ctorParameters: () => [], propDecorators: { formStepper: [{ type: i0.Input, args: [{ isSignal: true, alias: "formStepper", required: true }] }], completed: [{ type: i0.Output, args: ["completed"] }] } });
476
+
477
+ class Step {
478
+ inputs;
479
+ config;
480
+ constructor(inputs, config) {
481
+ this.inputs = inputs;
482
+ this.config = config;
483
+ }
484
+ }
485
+
486
+ class Input {
487
+ type;
488
+ returnKey;
489
+ label;
490
+ validators;
491
+ defaultValue;
492
+ constructor(type, defaultValue, returnKey, label, validators) {
493
+ this.type = type;
494
+ this.returnKey = returnKey;
495
+ this.label = label;
496
+ this.validators = validators;
497
+ this.defaultValue = (type === InputType.Checkbox ? (defaultValue === null ? false : defaultValue) : defaultValue);
498
+ }
499
+ }
500
+
501
+ class Select {
502
+ items;
503
+ currentIndex;
504
+ current;
505
+ constructor(items, currentIndex) {
506
+ this.items = items;
507
+ this.currentIndex = currentIndex;
508
+ this.current = currentIndex === null ? null : this.items[currentIndex];
509
+ }
510
+ }
511
+
512
+ function required(errorText) {
513
+ const name = (params) => `${params.key}-required`;
514
+ const fn = (params) => (control) => {
515
+ const customName = `${params.key}-required`;
516
+ return control.value.length > 0 ? null : { [customName]: true };
517
+ };
518
+ return {
519
+ kind: 'required',
520
+ name,
521
+ fn,
522
+ errorText,
523
+ };
524
+ }
525
+ function check(errorText) {
526
+ const name = (params) => `${params.key}-check`;
527
+ const fn = (params) => (control) => {
528
+ const customName = `${params.key}-check`;
529
+ const parsed = control.value === 'true';
530
+ return typeof control.value === 'string' ? (parsed ? null : { [customName]: true }) : null;
531
+ };
532
+ return {
533
+ kind: 'check',
534
+ name,
535
+ fn,
536
+ errorText,
537
+ };
538
+ }
539
+ function confirm(confirmLabel, errorText) {
540
+ const name = (params) => `${params.key}-confirm`;
541
+ const fn = (params) => (control) => {
542
+ const customName = `${params.key}-confirm`;
543
+ return control.get(params.key)?.value !== control.get(params.confirmKey)?.value
544
+ ? { [customName]: true }
545
+ : null;
546
+ };
547
+ return {
548
+ kind: 'confirm',
549
+ name,
550
+ fn,
551
+ errorText,
552
+ confirmLabel,
553
+ };
554
+ }
555
+ function minLength(min, errorText) {
556
+ const name = (params) => `${params.key}-minLength`;
557
+ const fn = (params) => (control) => {
558
+ const customName = `${params.key}-minLength`;
559
+ return control.value.length < min ? { [customName]: true } : null;
560
+ };
561
+ return {
562
+ kind: 'minLength',
563
+ name,
564
+ fn,
565
+ errorText,
566
+ };
567
+ }
568
+ function maxLength(max, errorText) {
569
+ const name = (params) => `${params.key}-maxLength`;
570
+ const fn = (params) => (control) => {
571
+ const customName = `${params.key}-maxLength`;
572
+ return control.value.length > max ? { [customName]: true } : null;
573
+ };
574
+ return {
575
+ kind: 'maxLength',
576
+ name,
577
+ fn,
578
+ errorText,
579
+ };
580
+ }
581
+ function min(min, errorText) {
582
+ const name = (params) => `${params.key}-min`;
583
+ const fn = (params) => (control) => {
584
+ const customName = `${params.key}-min`;
585
+ const parsed = Number(control.value);
586
+ return Number.isNaN(parsed)
587
+ ? { [customName]: true }
588
+ : parsed < min
589
+ ? { [customName]: true }
590
+ : null;
591
+ };
592
+ return {
593
+ kind: 'min',
594
+ name,
595
+ fn,
596
+ errorText,
597
+ };
598
+ }
599
+ function max(max, errorText) {
600
+ const name = (params) => `${params.key}-max`;
601
+ const fn = (params) => (control) => {
602
+ const customName = `${params.key}-max`;
603
+ const parsed = Number(control.value);
604
+ return Number.isNaN(parsed)
605
+ ? { [customName]: true }
606
+ : parsed > max
607
+ ? { [customName]: true }
608
+ : null;
609
+ };
610
+ return {
611
+ kind: 'max',
612
+ name,
613
+ fn,
614
+ errorText,
615
+ };
616
+ }
617
+ function integer(errorText) {
618
+ const name = (params) => `${params.key}-integer`;
619
+ const fn = (params) => (control) => {
620
+ const customName = `${params.key}-integer`;
621
+ const parsed = Number(control.value);
622
+ return Number.isNaN(parsed)
623
+ ? { [customName]: true }
624
+ : Number.isInteger(parsed)
625
+ ? null
626
+ : { [customName]: true };
627
+ };
628
+ return {
629
+ kind: 'integer',
630
+ name,
631
+ fn,
632
+ errorText,
633
+ };
634
+ }
635
+ function pattern(pattern, errorText) {
636
+ const name = (params) => `${params.key}-pattern`;
637
+ const fn = (params) => (control) => {
638
+ const customName = `${params.key}-pattern`;
639
+ return pattern.test(control.value) ? null : { [customName]: true };
640
+ };
641
+ return {
642
+ kind: 'pattern',
643
+ name,
644
+ fn,
645
+ errorText,
646
+ };
647
+ }
648
+ function strongPassword(errorText) {
649
+ const name = (params) => `${params.key}-strongPassword`;
650
+ const fn = (params) => (control) => {
651
+ const customName = `${params.key}-strongPassword`;
652
+ const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_\-+=]).{8,}$/;
653
+ return regex.test(control.value) ? null : { [customName]: true };
654
+ };
655
+ return {
656
+ kind: 'strongPassword',
657
+ name,
658
+ fn,
659
+ errorText,
660
+ };
661
+ }
662
+ function email(errorText) {
663
+ const name = (params) => `${params.key}-email`;
664
+ const fn = (params) => (control) => {
665
+ const customName = `${params.key}-email`;
666
+ const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
667
+ return regex.test(control.value) ? null : { [customName]: true };
668
+ };
669
+ return {
670
+ kind: 'email',
671
+ name,
672
+ fn,
673
+ errorText,
674
+ };
675
+ }
676
+ function phone(errorText) {
677
+ const name = (params) => `${params.key}-phone`;
678
+ const fn = (params) => (control) => {
679
+ const customName = `${params.key}-phone`;
680
+ const regex = /^\+?[0-9]{7,15}$/;
681
+ const cleared = control.value.replace(/\s|-/g, '');
682
+ return regex.test(cleared) ? null : { [customName]: true };
683
+ };
684
+ return {
685
+ kind: 'phone',
686
+ name,
687
+ fn,
688
+ errorText,
689
+ };
690
+ }
691
+ function minDate(min, errorText) {
692
+ const name = (params) => `${params.key}-minDate`;
693
+ const fn = (params) => (control) => {
694
+ const customName = `${params.key}-minDate`;
695
+ const parsed = control.value === '' ? null : new Date(control.value);
696
+ return parsed === null
697
+ ? { [customName]: true }
698
+ : parsed.getTime() < min.getTime()
699
+ ? { [customName]: true }
700
+ : null;
701
+ };
702
+ return {
703
+ kind: 'minDate',
704
+ name,
705
+ fn,
706
+ errorText,
707
+ };
708
+ }
709
+ function maxDate(max, errorText) {
710
+ const name = (params) => `${params.key}-maxDate`;
711
+ const fn = (params) => (control) => {
712
+ const customName = `${params.key}-maxDate`;
713
+ const parsed = control.value === '' ? null : new Date(control.value);
714
+ return parsed === null
715
+ ? { [customName]: true }
716
+ : parsed.getTime() > max.getTime()
717
+ ? { [customName]: true }
718
+ : null;
719
+ };
720
+ return {
721
+ kind: 'maxDate',
722
+ name,
723
+ fn,
724
+ errorText,
725
+ };
726
+ }
727
+
728
+ /**
729
+ * Generated bundle index. Do not edit.
730
+ */
731
+
732
+ export { FormStepper, FormStepperComponent, Input, InputType, Select, Step, check, confirm, email, integer, max, maxDate, maxLength, min, minDate, minLength, pattern, phone, required, strongPassword };
733
+ //# sourceMappingURL=ngx-form-stepper.mjs.map