@ngneers/controls 0.0.1-next.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/fesm2022/ngneers-controls-accordion.mjs +234 -0
- package/fesm2022/ngneers-controls-accordion.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api-ng.mjs +959 -0
- package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api-resize.mjs +712 -0
- package/fesm2022/ngneers-controls-api-resize.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api.mjs +347 -0
- package/fesm2022/ngneers-controls-api.mjs.map +1 -0
- package/fesm2022/ngneers-controls-avatar.mjs +77 -0
- package/fesm2022/ngneers-controls-avatar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-base.mjs +620 -0
- package/fesm2022/ngneers-controls-base.mjs.map +1 -0
- package/fesm2022/ngneers-controls-breadcrumb.mjs +100 -0
- package/fesm2022/ngneers-controls-breadcrumb.mjs.map +1 -0
- package/fesm2022/ngneers-controls-button-group.mjs +110 -0
- package/fesm2022/ngneers-controls-button-group.mjs.map +1 -0
- package/fesm2022/ngneers-controls-button.mjs +83 -0
- package/fesm2022/ngneers-controls-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-calendar-time-CJT5AFlA.mjs +74 -0
- package/fesm2022/ngneers-controls-calendar-time-CJT5AFlA.mjs.map +1 -0
- package/fesm2022/ngneers-controls-calendar.mjs +801 -0
- package/fesm2022/ngneers-controls-calendar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-checkbox.mjs +63 -0
- package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -0
- package/fesm2022/ngneers-controls-chip.mjs +55 -0
- package/fesm2022/ngneers-controls-chip.mjs.map +1 -0
- package/fesm2022/ngneers-controls-default-icons.mjs +82 -0
- package/fesm2022/ngneers-controls-default-icons.mjs.map +1 -0
- package/fesm2022/ngneers-controls-defer.mjs +72 -0
- package/fesm2022/ngneers-controls-defer.mjs.map +1 -0
- package/fesm2022/ngneers-controls-dialog.mjs +407 -0
- package/fesm2022/ngneers-controls-dialog.mjs.map +1 -0
- package/fesm2022/ngneers-controls-directives.mjs +498 -0
- package/fesm2022/ngneers-controls-directives.mjs.map +1 -0
- package/fesm2022/ngneers-controls-drawer.mjs +271 -0
- package/fesm2022/ngneers-controls-drawer.mjs.map +1 -0
- package/fesm2022/ngneers-controls-edit-inplace.mjs +127 -0
- package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -0
- package/fesm2022/ngneers-controls-errors.mjs +329 -0
- package/fesm2022/ngneers-controls-errors.mjs.map +1 -0
- package/fesm2022/ngneers-controls-filter.mjs +708 -0
- package/fesm2022/ngneers-controls-filter.mjs.map +1 -0
- package/fesm2022/ngneers-controls-hint.mjs +153 -0
- package/fesm2022/ngneers-controls-hint.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs +170 -0
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs +170 -0
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n.mjs +57 -0
- package/fesm2022/ngneers-controls-i18n.mjs.map +1 -0
- package/fesm2022/ngneers-controls-icon.mjs +195 -0
- package/fesm2022/ngneers-controls-icon.mjs.map +1 -0
- package/fesm2022/ngneers-controls-inplace.mjs +150 -0
- package/fesm2022/ngneers-controls-inplace.mjs.map +1 -0
- package/fesm2022/ngneers-controls-input-field.mjs +165 -0
- package/fesm2022/ngneers-controls-input-field.mjs.map +1 -0
- package/fesm2022/ngneers-controls-input.mjs +72 -0
- package/fesm2022/ngneers-controls-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-item-view.mjs +473 -0
- package/fesm2022/ngneers-controls-item-view.mjs.map +1 -0
- package/fesm2022/ngneers-controls-list-box.mjs +281 -0
- package/fesm2022/ngneers-controls-list-box.mjs.map +1 -0
- package/fesm2022/ngneers-controls-mask-input.mjs +888 -0
- package/fesm2022/ngneers-controls-mask-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-menu.mjs +371 -0
- package/fesm2022/ngneers-controls-menu.mjs.map +1 -0
- package/fesm2022/ngneers-controls-message.mjs +30 -0
- package/fesm2022/ngneers-controls-message.mjs.map +1 -0
- package/fesm2022/ngneers-controls-number-input.mjs +366 -0
- package/fesm2022/ngneers-controls-number-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-paginator.mjs +129 -0
- package/fesm2022/ngneers-controls-paginator.mjs.map +1 -0
- package/fesm2022/ngneers-controls-popover.mjs +215 -0
- package/fesm2022/ngneers-controls-popover.mjs.map +1 -0
- package/fesm2022/ngneers-controls-progress.mjs +98 -0
- package/fesm2022/ngneers-controls-progress.mjs.map +1 -0
- package/fesm2022/ngneers-controls-radio.mjs +152 -0
- package/fesm2022/ngneers-controls-radio.mjs.map +1 -0
- package/fesm2022/ngneers-controls-roving-focus.mjs +323 -0
- package/fesm2022/ngneers-controls-roving-focus.mjs.map +1 -0
- package/fesm2022/ngneers-controls-scroll-shadow.mjs +65 -0
- package/fesm2022/ngneers-controls-scroll-shadow.mjs.map +1 -0
- package/fesm2022/ngneers-controls-scroller.mjs +308 -0
- package/fesm2022/ngneers-controls-scroller.mjs.map +1 -0
- package/fesm2022/ngneers-controls-select-button.mjs +58 -0
- package/fesm2022/ngneers-controls-select-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-select.mjs +417 -0
- package/fesm2022/ngneers-controls-select.mjs.map +1 -0
- package/fesm2022/ngneers-controls-slider.mjs +167 -0
- package/fesm2022/ngneers-controls-slider.mjs.map +1 -0
- package/fesm2022/ngneers-controls-snackbar.mjs +414 -0
- package/fesm2022/ngneers-controls-snackbar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-spin-buttons.mjs +126 -0
- package/fesm2022/ngneers-controls-spin-buttons.mjs.map +1 -0
- package/fesm2022/ngneers-controls-spinner.mjs +184 -0
- package/fesm2022/ngneers-controls-spinner.mjs.map +1 -0
- package/fesm2022/ngneers-controls-splitter.mjs +604 -0
- package/fesm2022/ngneers-controls-splitter.mjs.map +1 -0
- package/fesm2022/ngneers-controls-state.mjs +185 -0
- package/fesm2022/ngneers-controls-state.mjs.map +1 -0
- package/fesm2022/ngneers-controls-switch.mjs +39 -0
- package/fesm2022/ngneers-controls-switch.mjs.map +1 -0
- package/fesm2022/ngneers-controls-table.mjs +2634 -0
- package/fesm2022/ngneers-controls-table.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tabs.mjs +336 -0
- package/fesm2022/ngneers-controls-tabs.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tag.mjs +30 -0
- package/fesm2022/ngneers-controls-tag.mjs.map +1 -0
- package/fesm2022/ngneers-controls-toast.mjs +350 -0
- package/fesm2022/ngneers-controls-toast.mjs.map +1 -0
- package/fesm2022/ngneers-controls-toggle-button.mjs +70 -0
- package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tooltip.mjs +506 -0
- package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tree.mjs +599 -0
- package/fesm2022/ngneers-controls-tree.mjs.map +1 -0
- package/fesm2022/ngneers-controls-upload.mjs +377 -0
- package/fesm2022/ngneers-controls-upload.mjs.map +1 -0
- package/fesm2022/ngneers-controls-utils-ng.mjs +411 -0
- package/fesm2022/ngneers-controls-utils-ng.mjs.map +1 -0
- package/fesm2022/ngneers-controls-utils.mjs +261 -0
- package/fesm2022/ngneers-controls-utils.mjs.map +1 -0
- package/fesm2022/ngneers-controls.mjs +6 -0
- package/fesm2022/ngneers-controls.mjs.map +1 -0
- package/package.json +302 -0
- package/types/ngneers-controls-accordion.d.ts +139 -0
- package/types/ngneers-controls-api-ng.d.ts +364 -0
- package/types/ngneers-controls-api-resize.d.ts +318 -0
- package/types/ngneers-controls-api.d.ts +145 -0
- package/types/ngneers-controls-avatar.d.ts +54 -0
- package/types/ngneers-controls-base.d.ts +277 -0
- package/types/ngneers-controls-breadcrumb.d.ts +272 -0
- package/types/ngneers-controls-button-group.d.ts +46 -0
- package/types/ngneers-controls-button.d.ts +48 -0
- package/types/ngneers-controls-calendar.d.ts +466 -0
- package/types/ngneers-controls-checkbox.d.ts +40 -0
- package/types/ngneers-controls-chip.d.ts +202 -0
- package/types/ngneers-controls-default-icons.d.ts +5 -0
- package/types/ngneers-controls-defer.d.ts +48 -0
- package/types/ngneers-controls-dialog.d.ts +399 -0
- package/types/ngneers-controls-directives.d.ts +171 -0
- package/types/ngneers-controls-drawer.d.ts +308 -0
- package/types/ngneers-controls-edit-inplace.d.ts +263 -0
- package/types/ngneers-controls-errors.d.ts +155 -0
- package/types/ngneers-controls-filter.d.ts +609 -0
- package/types/ngneers-controls-hint.d.ts +88 -0
- package/types/ngneers-controls-i18n-translations-de.d.ts +164 -0
- package/types/ngneers-controls-i18n-translations-en.d.ts +164 -0
- package/types/ngneers-controls-i18n.d.ts +186 -0
- package/types/ngneers-controls-icon.d.ts +68 -0
- package/types/ngneers-controls-inplace.d.ts +98 -0
- package/types/ngneers-controls-input-field.d.ts +248 -0
- package/types/ngneers-controls-input.d.ts +30 -0
- package/types/ngneers-controls-item-view.d.ts +215 -0
- package/types/ngneers-controls-list-box.d.ts +334 -0
- package/types/ngneers-controls-mask-input.d.ts +434 -0
- package/types/ngneers-controls-menu.d.ts +192 -0
- package/types/ngneers-controls-message.d.ts +21 -0
- package/types/ngneers-controls-number-input.d.ts +146 -0
- package/types/ngneers-controls-paginator.d.ts +255 -0
- package/types/ngneers-controls-popover.d.ts +116 -0
- package/types/ngneers-controls-progress.d.ts +49 -0
- package/types/ngneers-controls-radio.d.ts +91 -0
- package/types/ngneers-controls-roving-focus.d.ts +107 -0
- package/types/ngneers-controls-scroll-shadow.d.ts +25 -0
- package/types/ngneers-controls-scroller.d.ts +151 -0
- package/types/ngneers-controls-select-button.d.ts +51 -0
- package/types/ngneers-controls-select.d.ts +409 -0
- package/types/ngneers-controls-slider.d.ts +57 -0
- package/types/ngneers-controls-snackbar.d.ts +330 -0
- package/types/ngneers-controls-spin-buttons.d.ts +69 -0
- package/types/ngneers-controls-spinner.d.ts +117 -0
- package/types/ngneers-controls-splitter.d.ts +465 -0
- package/types/ngneers-controls-state.d.ts +102 -0
- package/types/ngneers-controls-switch.d.ts +18 -0
- package/types/ngneers-controls-table.d.ts +3127 -0
- package/types/ngneers-controls-tabs.d.ts +118 -0
- package/types/ngneers-controls-tag.d.ts +21 -0
- package/types/ngneers-controls-toast.d.ts +298 -0
- package/types/ngneers-controls-toggle-button.d.ts +48 -0
- package/types/ngneers-controls-tooltip.d.ts +189 -0
- package/types/ngneers-controls-tree.d.ts +409 -0
- package/types/ngneers-controls-upload.d.ts +347 -0
- package/types/ngneers-controls-utils-ng.d.ts +129 -0
- package/types/ngneers-controls-utils.d.ts +130 -0
- package/types/ngneers-controls.d.ts +2 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, input, signal, computed, DestroyRef, effect, Directive } from '@angular/core';
|
|
3
|
+
import { NgControl, ControlContainer } from '@angular/forms';
|
|
4
|
+
import { NGN_CONTROL } from '@ngneers/controls/base';
|
|
5
|
+
import '@ngneers/controls/hint';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Multi-provider token for validation error message maps.
|
|
9
|
+
* @category providers
|
|
10
|
+
*/
|
|
11
|
+
const NGN_ERRORS_MESSAGES = new InjectionToken('NGN_ERRORS_MESSAGES', {
|
|
12
|
+
factory: () => [],
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Provide custom validation error messages that are merged with defaults.
|
|
16
|
+
* @category providers
|
|
17
|
+
*/
|
|
18
|
+
function provideNgnErrorsMessages(messages) {
|
|
19
|
+
return {
|
|
20
|
+
provide: NGN_ERRORS_MESSAGES,
|
|
21
|
+
useValue: messages,
|
|
22
|
+
multi: true,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Inject all provided validation message maps as a single merged object.
|
|
27
|
+
* @category providers
|
|
28
|
+
*/
|
|
29
|
+
function injectNgnErrorsMessages() {
|
|
30
|
+
return Object.assign({}, ...inject(NGN_ERRORS_MESSAGES));
|
|
31
|
+
}
|
|
32
|
+
const defaultNgnErrorsMessages = {
|
|
33
|
+
required: 'Required',
|
|
34
|
+
email: 'Enter a valid email address',
|
|
35
|
+
minlength: ({ params }) => {
|
|
36
|
+
const requiredLength = params['requiredLength'];
|
|
37
|
+
return `Use at least ${requiredLength} characters`;
|
|
38
|
+
},
|
|
39
|
+
maxlength: ({ params }) => {
|
|
40
|
+
const requiredLength = params['requiredLength'];
|
|
41
|
+
return `Use at most ${requiredLength} characters`;
|
|
42
|
+
},
|
|
43
|
+
min: ({ params }) => {
|
|
44
|
+
const min = params['min'];
|
|
45
|
+
return `Must be at least ${min}`;
|
|
46
|
+
},
|
|
47
|
+
max: ({ params }) => {
|
|
48
|
+
const max = params['max'];
|
|
49
|
+
return `Must be at most ${max}`;
|
|
50
|
+
},
|
|
51
|
+
pattern: 'Invalid format',
|
|
52
|
+
};
|
|
53
|
+
function resolveNgnErrorMessage(context, messages) {
|
|
54
|
+
const resolver = messages[context.key];
|
|
55
|
+
if (typeof resolver === 'function') {
|
|
56
|
+
return resolver(context) ?? context.key;
|
|
57
|
+
}
|
|
58
|
+
if (resolver) {
|
|
59
|
+
return resolver;
|
|
60
|
+
}
|
|
61
|
+
if (typeof context.value === 'string') {
|
|
62
|
+
return context.value;
|
|
63
|
+
}
|
|
64
|
+
if (isRecord(context.value) && typeof context.value['message'] === 'string') {
|
|
65
|
+
return context.value['message'];
|
|
66
|
+
}
|
|
67
|
+
return context.key;
|
|
68
|
+
}
|
|
69
|
+
function paramsFromValue(value) {
|
|
70
|
+
if (!isRecord(value)) {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
return Object.fromEntries(Object.entries(value).filter(([key]) => key !== 'message' && !isControlNameKey(key)));
|
|
74
|
+
}
|
|
75
|
+
function isRecord(value) {
|
|
76
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
77
|
+
}
|
|
78
|
+
function isControlNameKey(key) {
|
|
79
|
+
return ['control', 'controlName', 'controls', 'controlNames', 'field', 'fields'].includes(key);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class NgnErrors {
|
|
83
|
+
/**
|
|
84
|
+
* Hint instance that receives the resolved validation state.
|
|
85
|
+
* @category inputs
|
|
86
|
+
*/
|
|
87
|
+
ngnErrorsHint = input(/* @ts-ignore */
|
|
88
|
+
...(ngDevMode ? [undefined, { debugName: "ngnErrorsHint" }] : /* istanbul ignore next */ []));
|
|
89
|
+
/**
|
|
90
|
+
* Interaction state that controls when errors become visible.
|
|
91
|
+
* @category inputs
|
|
92
|
+
*/
|
|
93
|
+
ngnErrorsShowOn = input('touched', /* @ts-ignore */
|
|
94
|
+
...(ngDevMode ? [{ debugName: "ngnErrorsShowOn" }] : /* istanbul ignore next */ []));
|
|
95
|
+
/**
|
|
96
|
+
* Whether to show the first matching error or all messages.
|
|
97
|
+
* @category inputs
|
|
98
|
+
*/
|
|
99
|
+
ngnErrorsMode = input('first', /* @ts-ignore */
|
|
100
|
+
...(ngDevMode ? [{ debugName: "ngnErrorsMode" }] : /* istanbul ignore next */ []));
|
|
101
|
+
/**
|
|
102
|
+
* Per-instance messages that override globally provided defaults.
|
|
103
|
+
* @category inputs
|
|
104
|
+
*/
|
|
105
|
+
ngnErrorsMessages = input(null, /* @ts-ignore */
|
|
106
|
+
...(ngDevMode ? [{ debugName: "ngnErrorsMessages" }] : /* istanbul ignore next */ []));
|
|
107
|
+
/**
|
|
108
|
+
* Additional errors supplied independently of Angular form validation.
|
|
109
|
+
* @category inputs
|
|
110
|
+
*/
|
|
111
|
+
ngnErrorsCustom = input(null, /* @ts-ignore */
|
|
112
|
+
...(ngDevMode ? [{ debugName: "ngnErrorsCustom" }] : /* istanbul ignore next */ []));
|
|
113
|
+
_ngControl = inject(NgControl, { optional: true, self: true });
|
|
114
|
+
_selfContainer = inject(ControlContainer, { optional: true, self: true });
|
|
115
|
+
_parentContainer = inject(ControlContainer, { optional: true, skipSelf: true });
|
|
116
|
+
_ngnControl = inject(NGN_CONTROL, {
|
|
117
|
+
optional: true,
|
|
118
|
+
self: true,
|
|
119
|
+
});
|
|
120
|
+
_globalMessages = injectNgnErrorsMessages();
|
|
121
|
+
_version = signal(0, /* @ts-ignore */
|
|
122
|
+
...(ngDevMode ? [{ debugName: "_version" }] : /* istanbul ignore next */ []));
|
|
123
|
+
errors = computed(() => {
|
|
124
|
+
this._version();
|
|
125
|
+
const messages = {
|
|
126
|
+
...defaultNgnErrorsMessages,
|
|
127
|
+
...this._globalMessages,
|
|
128
|
+
...this.ngnErrorsMessages(),
|
|
129
|
+
};
|
|
130
|
+
return [
|
|
131
|
+
...this._normalizeErrors(this._hostControl()?.errors, 'control', messages),
|
|
132
|
+
...this._normalizeGroupErrors(messages),
|
|
133
|
+
...this._normalizeCustomErrors(messages),
|
|
134
|
+
];
|
|
135
|
+
}, /* @ts-ignore */
|
|
136
|
+
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
137
|
+
firstError = computed(() => this.errors()[0] ?? null, /* @ts-ignore */
|
|
138
|
+
...(ngDevMode ? [{ debugName: "firstError" }] : /* istanbul ignore next */ []));
|
|
139
|
+
pending = computed(() => {
|
|
140
|
+
this._version();
|
|
141
|
+
return this._hostControl()?.pending ?? false;
|
|
142
|
+
}, /* @ts-ignore */
|
|
143
|
+
...(ngDevMode ? [{ debugName: "pending" }] : /* istanbul ignore next */ []));
|
|
144
|
+
visible = computed(() => {
|
|
145
|
+
if (!this.errors().length && !this.pending()) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const control = this._hostControl();
|
|
149
|
+
const showOn = this.ngnErrorsShowOn();
|
|
150
|
+
switch (showOn) {
|
|
151
|
+
case 'always':
|
|
152
|
+
return true;
|
|
153
|
+
case 'never':
|
|
154
|
+
return false;
|
|
155
|
+
case 'dirty':
|
|
156
|
+
return control?.dirty ?? readNgnBoolean(this._ngnControl, 'dirty');
|
|
157
|
+
case 'submitted':
|
|
158
|
+
return this._submitted();
|
|
159
|
+
case 'touched':
|
|
160
|
+
default:
|
|
161
|
+
return control?.touched ?? readNgnBoolean(this._ngnControl, 'touched');
|
|
162
|
+
}
|
|
163
|
+
}, /* @ts-ignore */
|
|
164
|
+
...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
165
|
+
message = computed(() => {
|
|
166
|
+
if (!this.visible()) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
if (this.pending()) {
|
|
170
|
+
return 'Validating...';
|
|
171
|
+
}
|
|
172
|
+
const errors = this.errors();
|
|
173
|
+
if (this.ngnErrorsMode() === 'all') {
|
|
174
|
+
return errors.map(error => error.message).join('\n') || null;
|
|
175
|
+
}
|
|
176
|
+
return errors[0]?.message ?? null;
|
|
177
|
+
}, /* @ts-ignore */
|
|
178
|
+
...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
179
|
+
state = computed(() => ({
|
|
180
|
+
visible: this.visible(),
|
|
181
|
+
pending: this.pending(),
|
|
182
|
+
errors: this.errors(),
|
|
183
|
+
firstError: this.firstError(),
|
|
184
|
+
message: this.message(),
|
|
185
|
+
}), /* @ts-ignore */
|
|
186
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
187
|
+
constructor() {
|
|
188
|
+
const destroyRef = inject(DestroyRef);
|
|
189
|
+
queueMicrotask(() => {
|
|
190
|
+
const controls = new Set([this._hostControl(), this._parentControl(), this._rootControl()].filter((control) => !!control));
|
|
191
|
+
for (const control of controls) {
|
|
192
|
+
this._watchControl(control, destroyRef);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
effect(() => {
|
|
196
|
+
this.ngnErrorsHint()?.setValidationState(this.state());
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
_watchControl(control, destroyRef) {
|
|
200
|
+
if (!control) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const markChanged = () => this._version.update(value => value + 1);
|
|
204
|
+
const statusSubscription = control.statusChanges?.subscribe(markChanged);
|
|
205
|
+
const valueSubscription = control.valueChanges?.subscribe(markChanged);
|
|
206
|
+
const eventsSubscription = control.events?.subscribe(markChanged);
|
|
207
|
+
destroyRef.onDestroy(() => {
|
|
208
|
+
statusSubscription?.unsubscribe();
|
|
209
|
+
valueSubscription?.unsubscribe();
|
|
210
|
+
eventsSubscription?.unsubscribe();
|
|
211
|
+
});
|
|
212
|
+
markChanged();
|
|
213
|
+
}
|
|
214
|
+
_hostControl() {
|
|
215
|
+
return this._ngControl?.control ?? this._selfContainer?.control ?? null;
|
|
216
|
+
}
|
|
217
|
+
_parentControl() {
|
|
218
|
+
return this._ngControl?.control?.parent ?? this._parentContainer?.control ?? null;
|
|
219
|
+
}
|
|
220
|
+
_rootControl() {
|
|
221
|
+
return this._hostControl()?.root ?? this._parentControl()?.root ?? null;
|
|
222
|
+
}
|
|
223
|
+
_submittedSource() {
|
|
224
|
+
const formDirective = this._selfContainer?.formDirective ?? this._parentContainer?.formDirective;
|
|
225
|
+
return (formDirective ?? this._selfContainer ?? this._parentContainer);
|
|
226
|
+
}
|
|
227
|
+
_submitted() {
|
|
228
|
+
return this._submittedSource()?.submitted ?? false;
|
|
229
|
+
}
|
|
230
|
+
_normalizeGroupErrors(messages) {
|
|
231
|
+
const parent = this._parentControl();
|
|
232
|
+
const host = this._hostControl();
|
|
233
|
+
if (!parent || parent === host) {
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
return this._normalizeErrors(parent.errors, 'group', messages).filter(error => this._isGroupErrorRelevant(error.value));
|
|
237
|
+
}
|
|
238
|
+
_normalizeCustomErrors(messages) {
|
|
239
|
+
const errors = this.ngnErrorsCustom();
|
|
240
|
+
if (!errors) {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
if (Array.isArray(errors)) {
|
|
244
|
+
return errors.map(error => {
|
|
245
|
+
if (typeof error === 'string') {
|
|
246
|
+
return this._createError(error, true, 'custom', messages);
|
|
247
|
+
}
|
|
248
|
+
return this._createCustomEntryError(error, messages);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
return this._normalizeErrors(errors, 'custom', messages);
|
|
252
|
+
}
|
|
253
|
+
_normalizeErrors(errors, source, messages) {
|
|
254
|
+
if (!errors) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
return Object.entries(errors).map(([key, value]) => this._createError(key, value, source, messages));
|
|
258
|
+
}
|
|
259
|
+
_createCustomEntryError(error, messages) {
|
|
260
|
+
const value = error.value ?? true;
|
|
261
|
+
const params = error.params ?? paramsFromValue(value);
|
|
262
|
+
const message = error.message ??
|
|
263
|
+
resolveNgnErrorMessage({
|
|
264
|
+
key: error.key,
|
|
265
|
+
value,
|
|
266
|
+
source: 'custom',
|
|
267
|
+
params,
|
|
268
|
+
}, messages);
|
|
269
|
+
return {
|
|
270
|
+
key: error.key,
|
|
271
|
+
value,
|
|
272
|
+
source: 'custom',
|
|
273
|
+
params,
|
|
274
|
+
message,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
_createError(key, value, source, messages) {
|
|
278
|
+
const params = paramsFromValue(value);
|
|
279
|
+
return {
|
|
280
|
+
key,
|
|
281
|
+
value,
|
|
282
|
+
source,
|
|
283
|
+
params,
|
|
284
|
+
message: resolveNgnErrorMessage({ key, value, source, params }, messages),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
_isGroupErrorRelevant(value) {
|
|
288
|
+
const name = this._ngControl?.name;
|
|
289
|
+
if (name === null || name === undefined || !isRecord(value)) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
const controlName = String(name);
|
|
293
|
+
return (hasMatchingName(value['control'], controlName) ||
|
|
294
|
+
hasMatchingName(value['controlName'], controlName) ||
|
|
295
|
+
hasMatchingName(value['field'], controlName) ||
|
|
296
|
+
hasMatchingName(value['controls'], controlName) ||
|
|
297
|
+
hasMatchingName(value['controlNames'], controlName) ||
|
|
298
|
+
hasMatchingName(value['fields'], controlName));
|
|
299
|
+
}
|
|
300
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnErrors, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
301
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: NgnErrors, isStandalone: true, selector: "[ngnErrors]", inputs: { ngnErrorsHint: { classPropertyName: "ngnErrorsHint", publicName: "ngnErrorsHint", isSignal: true, isRequired: false, transformFunction: null }, ngnErrorsShowOn: { classPropertyName: "ngnErrorsShowOn", publicName: "ngnErrorsShowOn", isSignal: true, isRequired: false, transformFunction: null }, ngnErrorsMode: { classPropertyName: "ngnErrorsMode", publicName: "ngnErrorsMode", isSignal: true, isRequired: false, transformFunction: null }, ngnErrorsMessages: { classPropertyName: "ngnErrorsMessages", publicName: "ngnErrorsMessages", isSignal: true, isRequired: false, transformFunction: null }, ngnErrorsCustom: { classPropertyName: "ngnErrorsCustom", publicName: "ngnErrorsCustom", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["ngnErrors"], ngImport: i0 });
|
|
302
|
+
}
|
|
303
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnErrors, decorators: [{
|
|
304
|
+
type: Directive,
|
|
305
|
+
args: [{
|
|
306
|
+
selector: '[ngnErrors]',
|
|
307
|
+
exportAs: 'ngnErrors',
|
|
308
|
+
}]
|
|
309
|
+
}], ctorParameters: () => [], propDecorators: { ngnErrorsHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnErrorsHint", required: false }] }], ngnErrorsShowOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnErrorsShowOn", required: false }] }], ngnErrorsMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnErrorsMode", required: false }] }], ngnErrorsMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnErrorsMessages", required: false }] }], ngnErrorsCustom: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnErrorsCustom", required: false }] }] } });
|
|
310
|
+
function hasMatchingName(value, controlName) {
|
|
311
|
+
if (Array.isArray(value)) {
|
|
312
|
+
return value.some(item => hasMatchingName(item, controlName));
|
|
313
|
+
}
|
|
314
|
+
if (value === null || value === undefined || isRecord(value)) {
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
return String(value) === controlName;
|
|
318
|
+
}
|
|
319
|
+
function readNgnBoolean(control, key) {
|
|
320
|
+
const value = control?.[key];
|
|
321
|
+
return typeof value === 'function' ? Boolean(value()) : Boolean(value);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Generated bundle index. Do not edit.
|
|
326
|
+
*/
|
|
327
|
+
|
|
328
|
+
export { NGN_ERRORS_MESSAGES, NgnErrors, defaultNgnErrorsMessages, injectNgnErrorsMessages, isRecord, paramsFromValue, provideNgnErrorsMessages, resolveNgnErrorMessage };
|
|
329
|
+
//# sourceMappingURL=ngneers-controls-errors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngneers-controls-errors.mjs","sources":["../../src/errors/messages.ts","../../src/errors/errors.ts","../../src/errors/ngneers-controls-errors.ts"],"sourcesContent":["import { inject, InjectionToken, type Provider } from '@angular/core';\n\nimport type { NgnErrorsMessageContext, NgnErrorsMessages } from './types';\n\n/**\n * Multi-provider token for validation error message maps.\n * @category providers\n */\nexport const NGN_ERRORS_MESSAGES = new InjectionToken<readonly NgnErrorsMessages[]>(\n 'NGN_ERRORS_MESSAGES',\n {\n factory: () => [],\n }\n);\n\n/**\n * Provide custom validation error messages that are merged with defaults.\n * @category providers\n */\nexport function provideNgnErrorsMessages(messages: NgnErrorsMessages): Provider {\n return {\n provide: NGN_ERRORS_MESSAGES,\n useValue: messages,\n multi: true,\n };\n}\n\n/**\n * Inject all provided validation message maps as a single merged object.\n * @category providers\n */\nexport function injectNgnErrorsMessages(): NgnErrorsMessages {\n return Object.assign({}, ...inject(NGN_ERRORS_MESSAGES));\n}\n\nexport const defaultNgnErrorsMessages: NgnErrorsMessages = {\n required: 'Required',\n email: 'Enter a valid email address',\n minlength: ({ params }) => {\n const requiredLength = params['requiredLength'];\n return `Use at least ${requiredLength} characters`;\n },\n maxlength: ({ params }) => {\n const requiredLength = params['requiredLength'];\n return `Use at most ${requiredLength} characters`;\n },\n min: ({ params }) => {\n const min = params['min'];\n return `Must be at least ${min}`;\n },\n max: ({ params }) => {\n const max = params['max'];\n return `Must be at most ${max}`;\n },\n pattern: 'Invalid format',\n};\n\nexport function resolveNgnErrorMessage(\n context: NgnErrorsMessageContext,\n messages: NgnErrorsMessages\n): string {\n const resolver = messages[context.key];\n if (typeof resolver === 'function') {\n return resolver(context) ?? context.key;\n }\n if (resolver) {\n return resolver;\n }\n if (typeof context.value === 'string') {\n return context.value;\n }\n if (isRecord(context.value) && typeof context.value['message'] === 'string') {\n return context.value['message'];\n }\n return context.key;\n}\n\nexport function paramsFromValue(value: unknown): Record<string, unknown> {\n if (!isRecord(value)) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(value).filter(([key]) => key !== 'message' && !isControlNameKey(key))\n );\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isControlNameKey(key: string): boolean {\n return ['control', 'controlName', 'controls', 'controlNames', 'field', 'fields'].includes(key);\n}\n","import {\n computed,\n DestroyRef,\n Directive,\n effect,\n inject,\n input,\n signal,\n type Signal,\n} from '@angular/core';\nimport {\n AbstractControl,\n ControlContainer,\n NgControl,\n type ValidationErrors,\n} from '@angular/forms';\nimport { NGN_CONTROL, type FullAnyNgnBase } from '@ngneers/controls/base';\nimport { NgnHint } from '@ngneers/controls/hint';\n\nimport {\n defaultNgnErrorsMessages,\n injectNgnErrorsMessages,\n isRecord,\n paramsFromValue,\n resolveNgnErrorMessage,\n} from './messages';\n\nimport type {\n NgnError,\n NgnErrorsCustom,\n NgnErrorsCustomEntry,\n NgnErrorsMessages,\n NgnErrorsMode,\n NgnErrorsShowOn,\n NgnErrorsSource,\n NgnErrorsState,\n} from './types';\n\n@Directive({\n selector: '[ngnErrors]',\n exportAs: 'ngnErrors',\n})\nexport class NgnErrors {\n /**\n * Hint instance that receives the resolved validation state.\n * @category inputs\n */\n public readonly ngnErrorsHint = input<NgnHint | undefined>();\n\n /**\n * Interaction state that controls when errors become visible.\n * @category inputs\n */\n public readonly ngnErrorsShowOn = input<NgnErrorsShowOn>('touched');\n\n /**\n * Whether to show the first matching error or all messages.\n * @category inputs\n */\n public readonly ngnErrorsMode = input<NgnErrorsMode>('first');\n\n /**\n * Per-instance messages that override globally provided defaults.\n * @category inputs\n */\n public readonly ngnErrorsMessages = input<NgnErrorsMessages | null>(null);\n\n /**\n * Additional errors supplied independently of Angular form validation.\n * @category inputs\n */\n public readonly ngnErrorsCustom = input<NgnErrorsCustom>(null);\n\n private readonly _ngControl = inject(NgControl, { optional: true, self: true });\n private readonly _selfContainer = inject(ControlContainer, { optional: true, self: true });\n private readonly _parentContainer = inject(ControlContainer, { optional: true, skipSelf: true });\n private readonly _ngnControl = inject(NGN_CONTROL, {\n optional: true,\n self: true,\n }) as FullAnyNgnBase | null;\n private readonly _globalMessages = injectNgnErrorsMessages();\n private readonly _version = signal(0);\n\n public readonly errors: Signal<readonly NgnError[]> = computed(() => {\n this._version();\n\n const messages = {\n ...defaultNgnErrorsMessages,\n ...this._globalMessages,\n ...this.ngnErrorsMessages(),\n };\n\n return [\n ...this._normalizeErrors(this._hostControl()?.errors, 'control', messages),\n ...this._normalizeGroupErrors(messages),\n ...this._normalizeCustomErrors(messages),\n ];\n });\n\n public readonly firstError = computed(() => this.errors()[0] ?? null);\n\n public readonly pending = computed(() => {\n this._version();\n return this._hostControl()?.pending ?? false;\n });\n\n public readonly visible = computed(() => {\n if (!this.errors().length && !this.pending()) {\n return false;\n }\n\n const control = this._hostControl();\n const showOn = this.ngnErrorsShowOn();\n\n switch (showOn) {\n case 'always':\n return true;\n case 'never':\n return false;\n case 'dirty':\n return control?.dirty ?? readNgnBoolean(this._ngnControl, 'dirty');\n case 'submitted':\n return this._submitted();\n case 'touched':\n default:\n return control?.touched ?? readNgnBoolean(this._ngnControl, 'touched');\n }\n });\n\n public readonly message = computed(() => {\n if (!this.visible()) {\n return null;\n }\n\n if (this.pending()) {\n return 'Validating...';\n }\n\n const errors = this.errors();\n if (this.ngnErrorsMode() === 'all') {\n return errors.map(error => error.message).join('\\n') || null;\n }\n\n return errors[0]?.message ?? null;\n });\n\n public readonly state: Signal<NgnErrorsState> = computed(() => ({\n visible: this.visible(),\n pending: this.pending(),\n errors: this.errors(),\n firstError: this.firstError(),\n message: this.message(),\n }));\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n\n queueMicrotask(() => {\n const controls = new Set(\n [this._hostControl(), this._parentControl(), this._rootControl()].filter(\n (control): control is AbstractControl => !!control\n )\n );\n for (const control of controls) {\n this._watchControl(control, destroyRef);\n }\n });\n\n effect(() => {\n this.ngnErrorsHint()?.setValidationState(this.state());\n });\n }\n\n private _watchControl(control: AbstractControl | null | undefined, destroyRef: DestroyRef): void {\n if (!control) {\n return;\n }\n\n const markChanged = () => this._version.update(value => value + 1);\n const statusSubscription = control.statusChanges?.subscribe(markChanged);\n const valueSubscription = control.valueChanges?.subscribe(markChanged);\n const eventsSubscription = (control as ControlWithEvents).events?.subscribe(markChanged);\n\n destroyRef.onDestroy(() => {\n statusSubscription?.unsubscribe();\n valueSubscription?.unsubscribe();\n eventsSubscription?.unsubscribe();\n });\n\n markChanged();\n }\n\n private _hostControl(): AbstractControl | null {\n return this._ngControl?.control ?? this._selfContainer?.control ?? null;\n }\n\n private _parentControl(): AbstractControl | null {\n return this._ngControl?.control?.parent ?? this._parentContainer?.control ?? null;\n }\n\n private _rootControl(): AbstractControl | null {\n return this._hostControl()?.root ?? this._parentControl()?.root ?? null;\n }\n\n private _submittedSource(): { submitted?: boolean } | null {\n const formDirective =\n this._selfContainer?.formDirective ?? this._parentContainer?.formDirective;\n return (formDirective ?? this._selfContainer ?? this._parentContainer) as {\n submitted?: boolean;\n } | null;\n }\n\n private _submitted(): boolean {\n return this._submittedSource()?.submitted ?? false;\n }\n\n private _normalizeGroupErrors(messages: NgnErrorsMessages): readonly NgnError[] {\n const parent = this._parentControl();\n const host = this._hostControl();\n if (!parent || parent === host) {\n return [];\n }\n\n return this._normalizeErrors(parent.errors, 'group', messages).filter(error =>\n this._isGroupErrorRelevant(error.value)\n );\n }\n\n private _normalizeCustomErrors(messages: NgnErrorsMessages): readonly NgnError[] {\n const errors = this.ngnErrorsCustom();\n if (!errors) {\n return [];\n }\n\n if (Array.isArray(errors)) {\n return errors.map(error => {\n if (typeof error === 'string') {\n return this._createError(error, true, 'custom', messages);\n }\n return this._createCustomEntryError(error, messages);\n });\n }\n\n return this._normalizeErrors(errors, 'custom', messages);\n }\n\n private _normalizeErrors(\n errors: ValidationErrors | null | undefined,\n source: NgnErrorsSource,\n messages: NgnErrorsMessages\n ): readonly NgnError[] {\n if (!errors) {\n return [];\n }\n\n return Object.entries(errors).map(([key, value]) =>\n this._createError(key, value, source, messages)\n );\n }\n\n private _createCustomEntryError(\n error: NgnErrorsCustomEntry,\n messages: NgnErrorsMessages\n ): NgnError {\n const value = error.value ?? true;\n const params = error.params ?? paramsFromValue(value);\n const message =\n error.message ??\n resolveNgnErrorMessage(\n {\n key: error.key,\n value,\n source: 'custom',\n params,\n },\n messages\n );\n\n return {\n key: error.key,\n value,\n source: 'custom',\n params,\n message,\n };\n }\n\n private _createError(\n key: string,\n value: unknown,\n source: NgnErrorsSource,\n messages: NgnErrorsMessages\n ): NgnError {\n const params = paramsFromValue(value);\n\n return {\n key,\n value,\n source,\n params,\n message: resolveNgnErrorMessage({ key, value, source, params }, messages),\n };\n }\n\n private _isGroupErrorRelevant(value: unknown): boolean {\n const name = this._ngControl?.name;\n if (name === null || name === undefined || !isRecord(value)) {\n return false;\n }\n\n const controlName = String(name);\n return (\n hasMatchingName(value['control'], controlName) ||\n hasMatchingName(value['controlName'], controlName) ||\n hasMatchingName(value['field'], controlName) ||\n hasMatchingName(value['controls'], controlName) ||\n hasMatchingName(value['controlNames'], controlName) ||\n hasMatchingName(value['fields'], controlName)\n );\n }\n}\n\ninterface ControlWithEvents {\n events?: { subscribe: (next: () => void) => { unsubscribe: () => void } };\n}\n\nfunction hasMatchingName(value: unknown, controlName: string): boolean {\n if (Array.isArray(value)) {\n return value.some(item => hasMatchingName(item, controlName));\n }\n if (value === null || value === undefined || isRecord(value)) {\n return false;\n }\n return String(value) === controlName;\n}\n\nfunction readNgnBoolean(control: FullAnyNgnBase | null, key: 'dirty' | 'touched'): boolean {\n const value = control?.[key as keyof FullAnyNgnBase];\n return typeof value === 'function' ? Boolean((value as () => unknown)()) : Boolean(value);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|