@nexterajs/ui 0.0.1 → 0.0.2
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/nexterajs-ui-core.mjs +189 -5
- package/fesm2022/nexterajs-ui-core.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-dropdowns.mjs +314 -50
- package/fesm2022/nexterajs-ui-dropdowns.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-file-uploader.mjs +6 -3
- package/fesm2022/nexterajs-ui-file-uploader.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-forms.mjs +729 -370
- package/fesm2022/nexterajs-ui-forms.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-grid.mjs +1188 -208
- package/fesm2022/nexterajs-ui-grid.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-intl.mjs +15 -5
- package/fesm2022/nexterajs-ui-intl.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-notify.mjs +351 -0
- package/fesm2022/nexterajs-ui-notify.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-pivot.mjs +146 -116
- package/fesm2022/nexterajs-ui-pivot.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-styling.mjs +568 -3
- package/fesm2022/nexterajs-ui-styling.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-tree-view.mjs +147 -18
- package/fesm2022/nexterajs-ui-tree-view.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-validation.mjs +247 -92
- package/fesm2022/nexterajs-ui-validation.mjs.map +1 -1
- package/fesm2022/nexterajs-ui.mjs +1 -0
- package/fesm2022/nexterajs-ui.mjs.map +1 -1
- package/package.json +5 -1
- package/styles/_dropdown.scss +149 -0
- package/styles/_editor.scss +23 -4
- package/styles/_icons.scss +92 -0
- package/styles/_mixins.scss +104 -1
- package/styles/_scrollbar.scss +134 -0
- package/styles/_toast.scss +243 -0
- package/styles/_tokens.scss +48 -0
- package/styles/index.scss +4 -0
- package/types/nexterajs-ui-core.d.ts +142 -22
- package/types/nexterajs-ui-dropdowns.d.ts +145 -27
- package/types/nexterajs-ui-file-uploader.d.ts +4 -1
- package/types/nexterajs-ui-forms.d.ts +103 -19
- package/types/nexterajs-ui-grid.d.ts +445 -57
- package/types/nexterajs-ui-notify.d.ts +147 -0
- package/types/nexterajs-ui-pivot.d.ts +35 -22
- package/types/nexterajs-ui-styling.d.ts +163 -3
- package/types/nexterajs-ui-tree-view.d.ts +50 -1
- package/types/nexterajs-ui-validation.d.ts +94 -15
- package/types/nexterajs-ui.d.ts +1 -0
|
@@ -49,6 +49,18 @@ const NXE_DEFAULT_OPTIONS = new InjectionToken('NXE_DEFAULT_OPTIONS', {
|
|
|
49
49
|
*
|
|
50
50
|
* Subclasses call {@link commitValue} on user interaction and {@link markAsTouched} on blur.
|
|
51
51
|
*/
|
|
52
|
+
let editorIdCounter = 0;
|
|
53
|
+
const nextEditorId = () => ++editorIdCounter;
|
|
54
|
+
/**
|
|
55
|
+
* dx size coercion: a bare number (or numeric string) means px, anything else passes through.
|
|
56
|
+
* Templates write the attribute form, so the string case is the common one.
|
|
57
|
+
*/
|
|
58
|
+
function cssSize(value) {
|
|
59
|
+
if (value === undefined || value === null || value === '') {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return /^-?\d+(\.\d+)?$/.test(String(value)) ? `${value}px` : String(value);
|
|
63
|
+
}
|
|
52
64
|
class NxeFormControlBase {
|
|
53
65
|
elementRef = inject(ElementRef);
|
|
54
66
|
/**
|
|
@@ -75,6 +87,44 @@ class NxeFormControlBase {
|
|
|
75
87
|
readOnly = input(false, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
76
88
|
/** Validation group this editor belongs to (its nested `nxe-validator` registers here). */
|
|
77
89
|
validationGroupInput = input(undefined, { ...(ngDevMode ? { debugName: "validationGroupInput" } : /* istanbul ignore next */ {}), alias: 'validationGroup' });
|
|
90
|
+
/**
|
|
91
|
+
* `id` for the INNER control, not the host.
|
|
92
|
+
*
|
|
93
|
+
* A caption written as `<label for="x">` has to reach the focusable element, and the host of
|
|
94
|
+
* a custom element is not it. Without this an editor cannot be labelled at all, which is why
|
|
95
|
+
* `aria-label` sits beside it: one of the two has to be available.
|
|
96
|
+
*/
|
|
97
|
+
inputId = input(undefined, /* @ts-ignore */
|
|
98
|
+
...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
99
|
+
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
100
|
+
ariaLabelledBy = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelledBy" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
|
|
101
|
+
/** Stable per instance, so the inner control always has an id something can point at. */
|
|
102
|
+
fallbackId = `nxe-editor-${nextEditorId()}`;
|
|
103
|
+
controlId = computed(() => this.inputId() ?? this.fallbackId, /* @ts-ignore */
|
|
104
|
+
...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
|
|
105
|
+
/**
|
|
106
|
+
* Ids for a popup listbox and its options.
|
|
107
|
+
*
|
|
108
|
+
* `aria-activedescendant` is how a combobox says which option is current while focus stays in
|
|
109
|
+
* the text field, and it can only point at an id — so the options need stable ones.
|
|
110
|
+
*/
|
|
111
|
+
panelId() {
|
|
112
|
+
return `${this.controlId()}-panel`;
|
|
113
|
+
}
|
|
114
|
+
optionId(index) {
|
|
115
|
+
return `${this.controlId()}-option-${index}`;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Whether a nested validator carries a `required` rule.
|
|
119
|
+
*
|
|
120
|
+
* Set by the validator rather than declared on the editor: the rule is where the requirement
|
|
121
|
+
* is actually stated, and duplicating it as an input would let the two disagree.
|
|
122
|
+
*/
|
|
123
|
+
required = signal(false, /* @ts-ignore */
|
|
124
|
+
...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
125
|
+
setRequired(value) {
|
|
126
|
+
this.required.set(value);
|
|
127
|
+
}
|
|
78
128
|
/** The current validation error message (set by a nested `nxe-validator`), or null. */
|
|
79
129
|
validationError = signal(null, /* @ts-ignore */
|
|
80
130
|
...(ngDevMode ? [{ debugName: "validationError" }] : /* istanbul ignore next */ []));
|
|
@@ -86,6 +136,47 @@ class NxeFormControlBase {
|
|
|
86
136
|
...(ngDevMode ? [{ debugName: "dirty" }] : /* istanbul ignore next */ []));
|
|
87
137
|
/** DevExtreme-compatible value-change event. */
|
|
88
138
|
onValueChanged = output();
|
|
139
|
+
/**
|
|
140
|
+
* dx's keyboard, focus and input events.
|
|
141
|
+
*
|
|
142
|
+
* Native events already reach the host, so these are not about capability — they are about
|
|
143
|
+
* the call site. A migrated `(onEnterKey)` handler should keep working without being
|
|
144
|
+
* rewritten as a `(keydown)` with a key check, and `onEnterKey` in particular has no native
|
|
145
|
+
* equivalent at all.
|
|
146
|
+
*/
|
|
147
|
+
onKeyDown = output();
|
|
148
|
+
onKeyUp = output();
|
|
149
|
+
onEnterKey = output();
|
|
150
|
+
onInput = output();
|
|
151
|
+
onChange = output();
|
|
152
|
+
onFocusIn = output();
|
|
153
|
+
onFocusOut = output();
|
|
154
|
+
/**
|
|
155
|
+
* When a typed value is committed: dx's `'change'` (on blur), `'input'` (per keystroke) or
|
|
156
|
+
* `'keyup'`.
|
|
157
|
+
*
|
|
158
|
+
* Honoured by the text editors. The number and date boxes stay on `'change'` whatever this
|
|
159
|
+
* says, because their displayed text is derived from the parsed value: committing mid-entry
|
|
160
|
+
* would rewrite the field while the user is still typing into it.
|
|
161
|
+
*/
|
|
162
|
+
valueChangeEvent = input('change', /* @ts-ignore */
|
|
163
|
+
...(ngDevMode ? [{ debugName: "valueChangeEvent" }] : /* istanbul ignore next */ []));
|
|
164
|
+
/** dx universal widget options. */
|
|
165
|
+
hint = input(undefined, /* @ts-ignore */
|
|
166
|
+
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
167
|
+
width = input(undefined, /* @ts-ignore */
|
|
168
|
+
...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
169
|
+
visible = input(true, { ...(ngDevMode ? { debugName: "visible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
170
|
+
tabIndex = input(undefined, /* @ts-ignore */
|
|
171
|
+
...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
|
|
172
|
+
elementAttr = input(undefined, /* @ts-ignore */
|
|
173
|
+
...(ngDevMode ? [{ debugName: "elementAttr" }] : /* istanbul ignore next */ []));
|
|
174
|
+
widthStyle = computed(() => cssSize(this.width()), /* @ts-ignore */
|
|
175
|
+
...(ngDevMode ? [{ debugName: "widthStyle" }] : /* istanbul ignore next */ []));
|
|
176
|
+
elementAttrClass = computed(() => this.elementAttr()?.['class'] ?? null, /* @ts-ignore */
|
|
177
|
+
...(ngDevMode ? [{ debugName: "elementAttrClass" }] : /* istanbul ignore next */ []));
|
|
178
|
+
elementAttrId = computed(() => this.elementAttr()?.['id'] ?? null, /* @ts-ignore */
|
|
179
|
+
...(ngDevMode ? [{ debugName: "elementAttrId" }] : /* istanbul ignore next */ []));
|
|
89
180
|
_onChange = () => { };
|
|
90
181
|
_onTouched = () => { };
|
|
91
182
|
/** Host element (the DevExtreme event payload `element`). */
|
|
@@ -137,6 +228,49 @@ class NxeFormControlBase {
|
|
|
137
228
|
element: this.element,
|
|
138
229
|
});
|
|
139
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Re-emit a native event in dx's shape.
|
|
233
|
+
*
|
|
234
|
+
* `onEnterKey` is the one that earns its keep: it has no native equivalent, so every call
|
|
235
|
+
* site would otherwise carry its own key check.
|
|
236
|
+
*/
|
|
237
|
+
emitEditorEvent(kind, event) {
|
|
238
|
+
const payload = { event, component: this, element: this.element };
|
|
239
|
+
switch (kind) {
|
|
240
|
+
case 'keydown':
|
|
241
|
+
this.onKeyDown.emit(payload);
|
|
242
|
+
if (event.key === 'Enter') {
|
|
243
|
+
this.onEnterKey.emit(payload);
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
case 'keyup':
|
|
247
|
+
this.onKeyUp.emit(payload);
|
|
248
|
+
break;
|
|
249
|
+
case 'input':
|
|
250
|
+
this.onInput.emit(payload);
|
|
251
|
+
break;
|
|
252
|
+
case 'change':
|
|
253
|
+
this.onChange.emit(payload);
|
|
254
|
+
break;
|
|
255
|
+
case 'focusin':
|
|
256
|
+
this.onFocusIn.emit(payload);
|
|
257
|
+
break;
|
|
258
|
+
case 'focusout':
|
|
259
|
+
this.onFocusOut.emit(payload);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Commit `next` if `valueChangeEvent` says this is the moment.
|
|
265
|
+
*
|
|
266
|
+
* Blur always commits, whatever the mode: a value the user typed and then left must not be
|
|
267
|
+
* discarded because the configured event never fired.
|
|
268
|
+
*/
|
|
269
|
+
commitOn(kind, next, event) {
|
|
270
|
+
if (kind === 'change' || this.valueChangeEvent() === kind) {
|
|
271
|
+
this.commitValue(next, event);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
140
274
|
/** Mark the control as touched (e.g. on blur), notifying Angular forms exactly once. */
|
|
141
275
|
markAsTouched() {
|
|
142
276
|
if (this.touched()) {
|
|
@@ -146,22 +280,36 @@ class NxeFormControlBase {
|
|
|
146
280
|
this.ngZone.run(() => this._onTouched());
|
|
147
281
|
}
|
|
148
282
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: NxeFormControlBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
149
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.5", type: NxeFormControlBase, isStandalone: true, inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, validationGroupInput: { classPropertyName: "validationGroupInput", publicName: "validationGroup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChanged: "onValueChanged" }, host: { properties: { "class.nxe-disabled": "disabled()", "class.nxe-readonly": "readOnly()", "class.
|
|
283
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.5", type: NxeFormControlBase, isStandalone: true, inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, validationGroupInput: { classPropertyName: "validationGroupInput", publicName: "validationGroup", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, valueChangeEvent: { classPropertyName: "valueChangeEvent", publicName: "valueChangeEvent", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, elementAttr: { classPropertyName: "elementAttr", publicName: "elementAttr", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChanged: "onValueChanged", onKeyDown: "onKeyDown", onKeyUp: "onKeyUp", onEnterKey: "onEnterKey", onInput: "onInput", onChange: "onChange", onFocusIn: "onFocusIn", onFocusOut: "onFocusOut" }, host: { listeners: { "keydown": "emitEditorEvent(\"keydown\", $event)", "keyup": "emitEditorEvent(\"keyup\", $event)", "input": "emitEditorEvent(\"input\", $event)", "change": "emitEditorEvent(\"change\", $event)", "focusin": "emitEditorEvent(\"focusin\", $event)", "focusout": "emitEditorEvent(\"focusout\", $event)" }, properties: { "attr.title": "hint() || null", "attr.id": "elementAttrId()", "class": "elementAttrClass()", "style.width": "widthStyle()", "style.display": "visible() ? null : \"none\"", "class.nxe-disabled": "disabled()", "class.nxe-readonly": "readOnly()", "class.nxe-state-readonly": "readOnly()" } }, ngImport: i0 });
|
|
150
284
|
}
|
|
151
285
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: NxeFormControlBase, decorators: [{
|
|
152
286
|
type: Directive,
|
|
153
287
|
args: [{
|
|
154
288
|
host: {
|
|
289
|
+
'[attr.title]': 'hint() || null',
|
|
290
|
+
'[attr.id]': 'elementAttrId()',
|
|
291
|
+
'[class]': 'elementAttrClass()',
|
|
292
|
+
'[style.width]': 'widthStyle()',
|
|
293
|
+
'[style.display]': 'visible() ? null : "none"',
|
|
294
|
+
// Listened for on the HOST, not on each inner control: these all bubble, so one place
|
|
295
|
+
// covers every editor and cannot collide with the handlers an editor already binds on
|
|
296
|
+
// its own input.
|
|
297
|
+
'(keydown)': 'emitEditorEvent("keydown", $event)',
|
|
298
|
+
'(keyup)': 'emitEditorEvent("keyup", $event)',
|
|
299
|
+
'(input)': 'emitEditorEvent("input", $event)',
|
|
300
|
+
'(change)': 'emitEditorEvent("change", $event)',
|
|
301
|
+
'(focusin)': 'emitEditorEvent("focusin", $event)',
|
|
302
|
+
'(focusout)': 'emitEditorEvent("focusout", $event)',
|
|
155
303
|
'[class.nxe-disabled]': 'disabled()',
|
|
156
304
|
'[class.nxe-readonly]': 'readOnly()',
|
|
157
|
-
// dx emits `
|
|
305
|
+
// dx emits `nxe-state-readonly` on a read-only editor, and legacy stylesheets lean on it
|
|
158
306
|
// for more than a cursor: the grid's editable-cell tint is keyed off its ABSENCE
|
|
159
307
|
// (`td:has(nxe-select-box):not(:has(.dx-state-readonly))`), so a missing class silently
|
|
160
308
|
// paints every read-only cell as editable. One binding here covers all eight editors.
|
|
161
|
-
'[class.
|
|
309
|
+
'[class.nxe-state-readonly]': 'readOnly()',
|
|
162
310
|
},
|
|
163
311
|
}]
|
|
164
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], validationGroupInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationGroup", required: false }] }], onValueChanged: [{ type: i0.Output, args: ["onValueChanged"] }] } });
|
|
312
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], validationGroupInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationGroup", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], onValueChanged: [{ type: i0.Output, args: ["onValueChanged"] }], onKeyDown: [{ type: i0.Output, args: ["onKeyDown"] }], onKeyUp: [{ type: i0.Output, args: ["onKeyUp"] }], onEnterKey: [{ type: i0.Output, args: ["onEnterKey"] }], onInput: [{ type: i0.Output, args: ["onInput"] }], onChange: [{ type: i0.Output, args: ["onChange"] }], onFocusIn: [{ type: i0.Output, args: ["onFocusIn"] }], onFocusOut: [{ type: i0.Output, args: ["onFocusOut"] }], valueChangeEvent: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueChangeEvent", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], elementAttr: [{ type: i0.Input, args: [{ isSignal: true, alias: "elementAttr", required: false }] }] } });
|
|
165
313
|
|
|
166
314
|
/**
|
|
167
315
|
* Base for no-template nested-option components (see {@link NxeConfigOption}).
|
|
@@ -257,8 +405,33 @@ function nxeOptionalBoolean(value) {
|
|
|
257
405
|
return value === undefined || value === null ? undefined : booleanAttribute(value);
|
|
258
406
|
}
|
|
259
407
|
|
|
408
|
+
/** Resolve `expr` against `item`. */
|
|
409
|
+
function nxeResolveExpr(expr, item) {
|
|
410
|
+
if (typeof expr === 'function') {
|
|
411
|
+
return expr(item);
|
|
412
|
+
}
|
|
413
|
+
if (!expr || expr === 'this') {
|
|
414
|
+
return item;
|
|
415
|
+
}
|
|
416
|
+
if (item == null || typeof item !== 'object') {
|
|
417
|
+
return undefined;
|
|
418
|
+
}
|
|
419
|
+
if (!expr.includes('.')) {
|
|
420
|
+
return item[expr];
|
|
421
|
+
}
|
|
422
|
+
return expr
|
|
423
|
+
.split('.')
|
|
424
|
+
.reduce((acc, key) => (acc == null || typeof acc !== 'object' ? undefined : acc[key]), item);
|
|
425
|
+
}
|
|
426
|
+
/** Resolve `expr` and render it as display text: `null`/`undefined` become the empty string. */
|
|
427
|
+
function nxeResolveText(expr, item) {
|
|
428
|
+
const resolved = nxeResolveExpr(expr, item);
|
|
429
|
+
return resolved == null ? '' : String(resolved);
|
|
430
|
+
}
|
|
431
|
+
|
|
260
432
|
/** DI token the editor provides so its nested `nxe-validator` can adapt it. */
|
|
261
433
|
const NXE_VALIDATION_TARGET = new InjectionToken('NXE_VALIDATION_TARGET');
|
|
434
|
+
const NXE_VALIDATION_GROUP = new InjectionToken('NXE_VALIDATION_GROUP');
|
|
262
435
|
|
|
263
436
|
/**
|
|
264
437
|
* Root registry mapping a `validationGroup` string to the `nxe-validator`s in it, mirroring
|
|
@@ -288,6 +461,17 @@ class NxeValidationGroupRegistry {
|
|
|
288
461
|
this.groups.delete(group);
|
|
289
462
|
}
|
|
290
463
|
}
|
|
464
|
+
/**
|
|
465
|
+
* Clear every member's error state without validating.
|
|
466
|
+
*
|
|
467
|
+
* dx's `ValidationGroup.reset()`. The distinction from `validate()` matters after a Cancel:
|
|
468
|
+
* the fields should stop showing errors, not be re-checked and light up again.
|
|
469
|
+
*/
|
|
470
|
+
reset(group) {
|
|
471
|
+
for (const member of this.groups.get(group) ?? []) {
|
|
472
|
+
member.reset?.();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
291
475
|
/** Validate every member of the group; valid (and empty) groups return `isValid: true`. */
|
|
292
476
|
validate(group) {
|
|
293
477
|
const set = this.groups.get(group);
|
|
@@ -322,5 +506,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
322
506
|
* Generated bundle index. Do not edit.
|
|
323
507
|
*/
|
|
324
508
|
|
|
325
|
-
export { NXE_DEFAULT_OPTIONS, NXE_OPTION, NXE_VALIDATION_TARGET, NxeConfigOptionBase, NxeFormControlBase, NxeTemplateDirective, NxeValidationGroupRegistry, coerceArray, nxeOptionalBoolean };
|
|
509
|
+
export { NXE_DEFAULT_OPTIONS, NXE_OPTION, NXE_VALIDATION_GROUP, NXE_VALIDATION_TARGET, NxeConfigOptionBase, NxeFormControlBase, NxeTemplateDirective, NxeValidationGroupRegistry, coerceArray, nxeOptionalBoolean, nxeResolveExpr, nxeResolveText };
|
|
326
510
|
//# sourceMappingURL=nexterajs-ui-core.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nexterajs-ui-core.mjs","sources":["../../../projects/nextera-ui/core/src/lib/core/tokens/nxe-default-options.token.ts","../../../projects/nextera-ui/core/src/lib/core/base/nxe-form-control.base.ts","../../../projects/nextera-ui/core/src/lib/core/base/nxe-config-option.base.ts","../../../projects/nextera-ui/core/src/lib/core/tokens/nxe-config-option.token.ts","../../../projects/nextera-ui/core/src/lib/core/directives/nxe-template.directive.ts","../../../projects/nextera-ui/core/src/lib/core/coercion/coerce-array.ts","../../../projects/nextera-ui/core/src/lib/core/coercion/optional-boolean.ts","../../../projects/nextera-ui/core/src/lib/core/validation/nxe-validation.types.ts","../../../projects/nextera-ui/core/src/lib/core/validation/nxe-validation-group-registry.service.ts","../../../projects/nextera-ui/core/src/lib/core/index.ts","../../../projects/nextera-ui/core/src/public-api.ts","../../../projects/nextera-ui/core/src/nexterajs-ui-core.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\n\r\n/**\r\n * Per-widget defaults, mirroring DevExtreme's `Widget.defaultOptions({ options: {...} })`.\r\n *\r\n * Every field is optional and every consumer resolves it as `binding ?? token ?? literal`, so\r\n * an application that provides nothing keeps the behaviour it has today.\r\n *\r\n * Only options that an application genuinely sets once and globally belong here. This is not a\r\n * second way to configure a component — a binding on the element always wins.\r\n */\r\nexport interface NxeGridDefaultOptions {\r\n hoverStateEnabled?: boolean;\r\n columnAutoWidth?: boolean;\r\n rowAlternationEnabled?: boolean;\r\n showColumnLines?: boolean;\r\n showRowLines?: boolean;\r\n showBorders?: boolean;\r\n wordWrapEnabled?: boolean;\r\n noDataText?: string;\r\n}\r\n\r\nexport interface NxePickerDefaultOptions {\r\n displayExpr?: string;\r\n valueExpr?: string;\r\n searchExpr?: string;\r\n searchEnabled?: boolean;\r\n showClearButton?: boolean;\r\n showDropDownButton?: boolean;\r\n placeholder?: string;\r\n}\r\n\r\nexport interface NxeDefaultOptions {\r\n readonly dataGrid?: NxeGridDefaultOptions;\r\n /** `nxe-tree-list` resolves against this slice instead of `dataGrid`, as dx does. */\r\n readonly treeList?: NxeGridDefaultOptions;\r\n readonly selectBox?: NxePickerDefaultOptions;\r\n readonly tagBox?: NxePickerDefaultOptions & { showSelectionControls?: boolean };\r\n /** Narrower than the other pickers: this one has no built-in search or drop-down button. */\r\n readonly dropDownBox?: Pick<\r\n NxePickerDefaultOptions,\r\n 'displayExpr' | 'valueExpr' | 'placeholder' | 'showClearButton'\r\n >;\r\n readonly dateBox?: { displayFormat?: string; placeholder?: string };\r\n readonly textBox?: { placeholder?: string; hoverStateEnabled?: boolean };\r\n readonly textArea?: { placeholder?: string; height?: number | string };\r\n readonly numberBox?: { format?: string };\r\n readonly button?: { focusStateEnabled?: boolean };\r\n}\r\n\r\n/**\r\n * Application-wide component defaults.\r\n *\r\n * DevExtreme applications configure a great deal through `defaultOptions` and then never write\r\n * those attributes again — so the templates carry no evidence that the option was ever set.\r\n * Without an equivalent here, a migrated application silently gets the library's literals: an\r\n * app that set `columnAutoWidth: true` once at bootstrap would find every grid laying its\r\n * columns out differently, with nothing in the markup to explain why.\r\n *\r\n * ```ts\r\n * providers: [\r\n * {\r\n * provide: NXE_DEFAULT_OPTIONS,\r\n * useValue: {\r\n * dataGrid: { columnAutoWidth: true, hoverStateEnabled: true },\r\n * treeList: { columnAutoWidth: true, hoverStateEnabled: true },\r\n * textArea: { height: 80 },\r\n * } satisfies NxeDefaultOptions,\r\n * },\r\n * ]\r\n * ```\r\n */\r\nexport const NXE_DEFAULT_OPTIONS = new InjectionToken<NxeDefaultOptions>('NXE_DEFAULT_OPTIONS', {\r\n providedIn: 'root',\r\n factory: () => ({}),\r\n});\r\n","import {\r\n booleanAttribute,\r\n computed,\r\n Directive,\r\n ElementRef,\r\n inject,\r\n input,\r\n model,\r\n NgZone,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor } from '@angular/forms';\r\nimport { NXE_DEFAULT_OPTIONS } from '../tokens/nxe-default-options.token';\r\nimport { NxeValueChangedEvent } from '../types/nxe-events';\r\nimport { NxeValidationTarget } from '../validation/nxe-validation.types';\r\n\r\n/**\r\n * Signal-based `ControlValueAccessor` base for every nxe form editor\r\n * (`nxe-text-box`, `nxe-number-box`, `nxe-date-box`, `nxe-check-box`, `nxe-text-area`,\r\n * `nxe-select-box`, `nxe-tag-box`, `nxe-radio`, ...).\r\n *\r\n * It supports BOTH template-driven (`[(ngModel)]`) and reactive (`formControlName`) forms\r\n * transparently, as well as DevExtreme-style `[value]` / `[(value)]` two-way binding, and\r\n * emits the DevExtreme-shaped {@link NxeValueChangedEvent} from `onValueChanged`.\r\n *\r\n * Concrete components MUST register themselves as the value accessor, e.g.:\r\n * ```ts\r\n * @Component({\r\n * selector: 'nxe-text-box',\r\n * providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NxeTextBoxComponent), multi: true }],\r\n * ...\r\n * })\r\n * export class NxeTextBoxComponent extends NxeFormControlBase<string> { ... }\r\n * ```\r\n *\r\n * Subclasses call {@link commitValue} on user interaction and {@link markAsTouched} on blur.\r\n */\r\n@Directive({\r\n host: {\r\n '[class.nxe-disabled]': 'disabled()',\r\n '[class.nxe-readonly]': 'readOnly()',\r\n // dx emits `dx-state-readonly` on a read-only editor, and legacy stylesheets lean on it\r\n // for more than a cursor: the grid's editable-cell tint is keyed off its ABSENCE\r\n // (`td:has(nxe-select-box):not(:has(.dx-state-readonly))`), so a missing class silently\r\n // paints every read-only cell as editable. One binding here covers all eight editors.\r\n '[class.dx-state-readonly]': 'readOnly()',\r\n },\r\n})\r\nexport abstract class NxeFormControlBase<T> implements ControlValueAccessor, NxeValidationTarget {\r\n protected readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\r\n /**\r\n * The app is zone-based (`provideZoneChangeDetection()`); writing back to Angular forms\r\n * from a signal context must run inside the zone or reactive forms lag a tick.\r\n */\r\n protected readonly ngZone = inject(NgZone);\r\n /** Application-wide defaults; each editor resolves `binding ?? this ?? literal`. */\r\n protected readonly nxeDefaults = inject(NXE_DEFAULT_OPTIONS);\r\n\r\n /**\r\n * The current value — single source of truth. Two-way bindable as `[(value)]` (DevExtreme\r\n * parity) and also driven by `writeValue` for `ngModel`/`formControlName`.\r\n */\r\n readonly value = model<T | null>(null);\r\n\r\n /** Disabled via the `[disabled]` input (DevExtreme parity); OR-combined with forms disabled. */\r\n readonly disabledInput = input(false, { alias: 'disabled', transform: booleanAttribute });\r\n private readonly disabledByForm = signal(false);\r\n /** Effective disabled state (input OR reactive-forms `setDisabledState`). */\r\n readonly disabled = computed(() => this.disabledInput() || this.disabledByForm());\r\n\r\n /** Read-only state (DevExtreme `[readOnly]`). */\r\n readonly readOnly = input(false, { transform: booleanAttribute });\r\n\r\n /** Validation group this editor belongs to (its nested `nxe-validator` registers here). */\r\n readonly validationGroupInput = input<string | undefined>(undefined, { alias: 'validationGroup' });\r\n\r\n /** The current validation error message (set by a nested `nxe-validator`), or null. */\r\n readonly validationError = signal<string | null>(null);\r\n\r\n /** Whether the control has been blurred at least once. */\r\n readonly touched = signal(false);\r\n /** Whether the value has been changed by the user at least once. */\r\n readonly dirty = signal(false);\r\n\r\n /** DevExtreme-compatible value-change event. */\r\n readonly onValueChanged = output<NxeValueChangedEvent<T>>();\r\n\r\n private _onChange: (value: T | null) => void = () => {};\r\n private _onTouched: () => void = () => {};\r\n\r\n /** Host element (the DevExtreme event payload `element`). */\r\n get element(): HTMLElement {\r\n return this.elementRef.nativeElement;\r\n }\r\n\r\n // --- NxeValidationTarget (consumed by a nested nxe-validator) ---\r\n\r\n getValue(): unknown {\r\n return this.value();\r\n }\r\n\r\n validationGroup(): string | undefined {\r\n return this.validationGroupInput();\r\n }\r\n\r\n setValidationError(message: string | null): void {\r\n this.validationError.set(message);\r\n }\r\n\r\n // --- ControlValueAccessor: forms -> component (no event emission) ---\r\n\r\n writeValue(value: T | null): void {\r\n this.value.set(value);\r\n }\r\n\r\n registerOnChange(fn: (value: T | null) => void): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this.disabledByForm.set(isDisabled);\r\n }\r\n\r\n // --- component -> forms (user interaction) ---\r\n\r\n /**\r\n * Commit a user-initiated value change: update the value, notify Angular forms (inside\r\n * `NgZone.run` so reactive forms detect it in this zone-based app), and emit the\r\n * DevExtreme-shaped `onValueChanged`. No-op when the value is unchanged.\r\n */\r\n protected commitValue(next: T | null, event: Event | null = null): void {\r\n const previousValue = this.value();\r\n if (Object.is(previousValue, next)) {\r\n return;\r\n }\r\n this.value.set(next);\r\n this.dirty.set(true);\r\n this.ngZone.run(() => this._onChange(next));\r\n this.onValueChanged.emit({\r\n value: next,\r\n previousValue,\r\n event,\r\n component: this,\r\n element: this.element,\r\n });\r\n }\r\n\r\n /** Mark the control as touched (e.g. on blur), notifying Angular forms exactly once. */\r\n protected markAsTouched(): void {\r\n if (this.touched()) {\r\n return;\r\n }\r\n this.touched.set(true);\r\n this.ngZone.run(() => this._onTouched());\r\n }\r\n}\r\n","import { Directive } from '@angular/core';\r\nimport { NxeConfigOption } from '../tokens/nxe-config-option.token';\r\n\r\n/**\r\n * Base for no-template nested-option components (see {@link NxeConfigOption}).\r\n *\r\n * Concrete options extend this, declare their inputs as signals, implement {@link nxeConfig}\r\n * (typically returning a `computed()` of those inputs), and register the {@link NXE_OPTION}\r\n * token so the parent can collect them:\r\n * ```ts\r\n * @Component({\r\n * selector: 'nxe-selection',\r\n * template: '',\r\n * providers: [{ provide: NXE_OPTION, useExisting: forwardRef(() => NxeSelectionComponent), multi: true }],\r\n * })\r\n * export class NxeSelectionComponent extends NxeConfigOptionBase<SelectionConfig> {\r\n * readonly nxeRole = 'selection';\r\n * readonly mode = input<'single' | 'multiple'>('single');\r\n * nxeConfig() { return { mode: this.mode() }; }\r\n * }\r\n * ```\r\n */\r\n@Directive()\r\nexport abstract class NxeConfigOptionBase<TConfig> implements NxeConfigOption<TConfig> {\r\n abstract readonly nxeRole: string;\r\n abstract nxeConfig(): TConfig;\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\n/**\r\n * Contract implemented by every flat `nxe-` nested-option component\r\n * (`nxe-column`, `nxe-selection`, `nxe-paging`, `nxe-summary`, `nxe-validation-rule`, ...).\r\n *\r\n * Nested options carry no template; they exist purely to declare configuration. Each one\r\n * exposes its current config as a signal-readable function and a `role` discriminator, so a\r\n * parent (`nxe-data-grid`, `nxe-select-box`, ...) can collect them via `contentChildren` and\r\n * derive a reactive config model — the mechanism that lets\r\n * `<nxe-data-grid><nxe-column/></nxe-data-grid>` mirror `<dx-data-grid><dxi-column/>`.\r\n */\r\nexport interface NxeConfigOption<TConfig = unknown> {\r\n /** Discriminator identifying the option kind, e.g. `'column'`, `'selection'`, `'paging'`. */\r\n readonly nxeRole: string;\r\n /** Returns the option's current configuration (reads signals; recomputes reactively). */\r\n nxeConfig(): TConfig;\r\n}\r\n\r\n/**\r\n * DI token every nested-option component provides (`multi: true`) so parents can query all\r\n * options with `contentChildren(NXE_OPTION)` without importing the concrete option classes.\r\n */\r\nexport const NXE_OPTION = new InjectionToken<NxeConfigOption>('NXE_OPTION');\r\n","import { computed, Directive, inject, input, TemplateRef } from '@angular/core';\r\n\r\n/**\r\n * `nxeTemplate` — drop-in replacement for DevExtreme's `*dxTemplate`.\r\n *\r\n * Captures a named `ng-template` so a parent container (select-box item template, grid\r\n * cell/header/edit templates, list item template, ...) can look it up by name and render it\r\n * with a context object. BOTH authoring forms resolve to the same {@link name}:\r\n *\r\n * - attribute form: `<ng-template nxeTemplate=\"cellContent\" let-data>` (psak-web style)\r\n * - dx microsyntax: `<div *nxeTemplate=\"let data of 'cellContent'\">` — desugars the name into\r\n * an `nxeTemplateOf` binding (orbit's mechanically-migrated `*dxTemplate` templates)\r\n *\r\n * Parents collect these via `contentChildren(NxeTemplateDirective)` and match on {@link name},\r\n * rendering with `ngTemplateOutlet` + an `ngTemplateOutletContext` of `{ $implicit: data, ... }`.\r\n */\r\n@Directive({\r\n selector: '[nxeTemplate]',\r\n})\r\nexport class NxeTemplateDirective {\r\n /** Attribute-form name (`nxeTemplate=\"name\"`); empty in microsyntax usage. */\r\n readonly attrName = input<string>('', { alias: 'nxeTemplate' });\r\n /** Microsyntax-form name (`*nxeTemplate=\"let x of 'name'\"` binds `nxeTemplateOf`). */\r\n readonly ofName = input<string | undefined>(undefined, { alias: 'nxeTemplateOf' });\r\n\r\n /** The template's lookup name, whichever form supplied it. */\r\n readonly name = computed(() => this.ofName() ?? this.attrName());\r\n\r\n readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);\r\n}\r\n","/**\r\n * Wrap a value in an array if it is not already one (null/undefined -> empty array).\r\n *\r\n * Mirrors `@angular/cdk/coercion`'s `coerceArray` so nxe components don't import CDK coercion\r\n * directly. (For boolean/number coercion use `booleanAttribute` / `numberAttribute` from\r\n * `@angular/core` directly on `input(...)`.)\r\n */\r\nexport function coerceArray<T>(value: T | readonly T[] | null | undefined): T[] {\r\n if (value == null) {\r\n return [];\r\n }\r\n return Array.isArray(value) ? [...value] : [value as T];\r\n}\r\n","import { booleanAttribute } from '@angular/core';\r\n\r\n/**\r\n * `booleanAttribute` that preserves \"unset\".\r\n *\r\n * An input resolved as `binding ?? token ?? literal` needs three states, but\r\n * `booleanAttribute` has two: it maps `undefined` to `false`, which makes \"nobody bound this\"\r\n * indistinguishable from \"someone bound false\" and silently removes the token rung.\r\n *\r\n * This keeps the attribute-form coercion (`showClearButton=\"false\"` is `false`, not the truthy\r\n * string) and passes `undefined` straight through.\r\n */\r\nexport function nxeOptionalBoolean(value: unknown): boolean | undefined {\r\n return value === undefined || value === null ? undefined : booleanAttribute(value);\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\n/** A single failed validation rule. */\r\nexport interface NxeBrokenRule {\r\n type: string;\r\n message: string;\r\n}\r\n\r\n/**\r\n * Result of validating a control or a validation group — shaped to match\r\n * DevExtreme's `ValidationGroup.validate()` / `dxValidator.validate()` return value so existing\r\n * handlers (`const r = event.validationGroup.validate(); if (r.isValid) {...}`) work unchanged.\r\n */\r\nexport interface NxeValidationResult {\r\n isValid: boolean;\r\n brokenRules: NxeBrokenRule[];\r\n status: 'valid' | 'invalid' | 'pending';\r\n}\r\n\r\n/**\r\n * Contract an editor exposes (via {@link NXE_VALIDATION_TARGET}) to the `nxe-validator` nested\r\n * inside it: read the current value, the editor's validation group, and push the invalid\r\n * message back so the editor can render it.\r\n */\r\nexport interface NxeValidationTarget {\r\n getValue(): unknown;\r\n validationGroup(): string | undefined;\r\n setValidationError(message: string | null): void;\r\n}\r\n\r\n/** DI token the editor provides so its nested `nxe-validator` can adapt it. */\r\nexport const NXE_VALIDATION_TARGET = new InjectionToken<NxeValidationTarget>(\r\n 'NXE_VALIDATION_TARGET',\r\n);\r\n\r\n/** A member registered in a validation group (an `nxe-validator`). */\r\nexport interface NxeValidationGroupMember {\r\n validate(): NxeValidationResult;\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { NxeBrokenRule, NxeValidationGroupMember, NxeValidationResult } from './nxe-validation.types';\r\n\r\n/**\r\n * Root registry mapping a `validationGroup` string to the `nxe-validator`s in it, mirroring\r\n * DevExtreme's global ValidationEngine.\r\n *\r\n * `nxe-button[validationGroup]` (and any caller) triggers {@link validate} for a group, which\r\n * runs every member validator and aggregates the result into the DevExtreme-shaped\r\n * {@link NxeValidationResult}.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class NxeValidationGroupRegistry {\r\n private readonly groups = new Map<string, Set<NxeValidationGroupMember>>();\r\n\r\n register(group: string, member: NxeValidationGroupMember): void {\r\n let set = this.groups.get(group);\r\n if (!set) {\r\n set = new Set();\r\n this.groups.set(group, set);\r\n }\r\n set.add(member);\r\n }\r\n\r\n unregister(group: string, member: NxeValidationGroupMember): void {\r\n const set = this.groups.get(group);\r\n if (!set) {\r\n return;\r\n }\r\n set.delete(member);\r\n if (set.size === 0) {\r\n this.groups.delete(group);\r\n }\r\n }\r\n\r\n /** Validate every member of the group; valid (and empty) groups return `isValid: true`. */\r\n validate(group: string): NxeValidationResult {\r\n const set = this.groups.get(group);\r\n const brokenRules: NxeBrokenRule[] = [];\r\n if (set) {\r\n for (const member of set) {\r\n const result = member.validate();\r\n if (!result.isValid) {\r\n brokenRules.push(...result.brokenRules);\r\n }\r\n }\r\n }\r\n return {\r\n isValid: brokenRules.length === 0,\r\n brokenRules,\r\n status: brokenRules.length === 0 ? 'valid' : 'invalid',\r\n };\r\n }\r\n}\r\n","// @nexterajs/ui — core abstractions shared by every component.\r\n\r\nexport * from './types/nxe-events';\r\nexport * from './base/nxe-form-control.base';\r\nexport * from './base/nxe-config-option.base';\r\nexport * from './tokens/nxe-config-option.token';\r\nexport * from './tokens/nxe-default-options.token';\r\nexport * from './directives/nxe-template.directive';\r\nexport * from './coercion/coerce-array';\r\nexport * from './coercion/optional-boolean';\r\nexport * from './validation/nxe-validation.types';\r\nexport * from './validation/nxe-validation-group-registry.service';\r\n","// @nexterajs/ui/core — public API.\r\nexport * from './lib/core/index';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nexterajs-ui-core.mjs","sources":["../../../projects/nextera-ui/core/src/lib/core/tokens/nxe-default-options.token.ts","../../../projects/nextera-ui/core/src/lib/core/base/nxe-form-control.base.ts","../../../projects/nextera-ui/core/src/lib/core/base/nxe-config-option.base.ts","../../../projects/nextera-ui/core/src/lib/core/tokens/nxe-config-option.token.ts","../../../projects/nextera-ui/core/src/lib/core/directives/nxe-template.directive.ts","../../../projects/nextera-ui/core/src/lib/core/coercion/coerce-array.ts","../../../projects/nextera-ui/core/src/lib/core/coercion/optional-boolean.ts","../../../projects/nextera-ui/core/src/lib/core/coercion/nxe-expr.ts","../../../projects/nextera-ui/core/src/lib/core/validation/nxe-validation.types.ts","../../../projects/nextera-ui/core/src/lib/core/validation/nxe-validation-group-registry.service.ts","../../../projects/nextera-ui/core/src/lib/core/index.ts","../../../projects/nextera-ui/core/src/public-api.ts","../../../projects/nextera-ui/core/src/nexterajs-ui-core.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * Per-widget defaults, mirroring DevExtreme's `Widget.defaultOptions({ options: {...} })`.\n *\n * Every field is optional and every consumer resolves it as `binding ?? token ?? literal`, so\n * an application that provides nothing keeps the behaviour it has today.\n *\n * Only options that an application genuinely sets once and globally belong here. This is not a\n * second way to configure a component — a binding on the element always wins.\n */\nexport interface NxeGridDefaultOptions {\n hoverStateEnabled?: boolean;\n columnAutoWidth?: boolean;\n rowAlternationEnabled?: boolean;\n showColumnLines?: boolean;\n showRowLines?: boolean;\n showBorders?: boolean;\n wordWrapEnabled?: boolean;\n noDataText?: string;\n}\n\nexport interface NxePickerDefaultOptions {\n displayExpr?: string;\n valueExpr?: string;\n searchExpr?: string;\n searchEnabled?: boolean;\n showClearButton?: boolean;\n showDropDownButton?: boolean;\n placeholder?: string;\n}\n\nexport interface NxeDefaultOptions {\n readonly dataGrid?: NxeGridDefaultOptions;\n /** `nxe-tree-list` resolves against this slice instead of `dataGrid`, as dx does. */\n readonly treeList?: NxeGridDefaultOptions;\n readonly selectBox?: NxePickerDefaultOptions;\n readonly tagBox?: NxePickerDefaultOptions & { showSelectionControls?: boolean };\n /** Narrower than the other pickers: this one has no built-in search or drop-down button. */\n readonly dropDownBox?: Pick<\n NxePickerDefaultOptions,\n 'displayExpr' | 'valueExpr' | 'placeholder' | 'showClearButton'\n >;\n readonly dateBox?: { displayFormat?: string; placeholder?: string; showClearButton?: boolean };\n readonly textBox?: { placeholder?: string; hoverStateEnabled?: boolean; showClearButton?: boolean };\n readonly textArea?: { placeholder?: string; height?: number | string };\n readonly numberBox?: { format?: string; showClearButton?: boolean };\n readonly button?: { focusStateEnabled?: boolean };\n}\n\n/**\n * Application-wide component defaults.\n *\n * DevExtreme applications configure a great deal through `defaultOptions` and then never write\n * those attributes again — so the templates carry no evidence that the option was ever set.\n * Without an equivalent here, a migrated application silently gets the library's literals: an\n * app that set `columnAutoWidth: true` once at bootstrap would find every grid laying its\n * columns out differently, with nothing in the markup to explain why.\n *\n * ```ts\n * providers: [\n * {\n * provide: NXE_DEFAULT_OPTIONS,\n * useValue: {\n * dataGrid: { columnAutoWidth: true, hoverStateEnabled: true },\n * treeList: { columnAutoWidth: true, hoverStateEnabled: true },\n * textArea: { height: 80 },\n * } satisfies NxeDefaultOptions,\n * },\n * ]\n * ```\n */\nexport const NXE_DEFAULT_OPTIONS = new InjectionToken<NxeDefaultOptions>('NXE_DEFAULT_OPTIONS', {\n providedIn: 'root',\n factory: () => ({}),\n});\n","import {\r\n booleanAttribute,\r\n computed,\r\n Directive,\r\n ElementRef,\r\n inject,\r\n input,\r\n model,\r\n NgZone,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor } from '@angular/forms';\r\nimport { NXE_DEFAULT_OPTIONS } from '../tokens/nxe-default-options.token';\r\nimport { NxeEditorEvent, NxeEditorEventKind } from '../types/nxe-events';\r\nimport { NxeValueChangedEvent } from '../types/nxe-events';\r\nimport { NxeValidationTarget } from '../validation/nxe-validation.types';\r\n\r\n/**\r\n * Signal-based `ControlValueAccessor` base for every nxe form editor\r\n * (`nxe-text-box`, `nxe-number-box`, `nxe-date-box`, `nxe-check-box`, `nxe-text-area`,\r\n * `nxe-select-box`, `nxe-tag-box`, `nxe-radio`, ...).\r\n *\r\n * It supports BOTH template-driven (`[(ngModel)]`) and reactive (`formControlName`) forms\r\n * transparently, as well as DevExtreme-style `[value]` / `[(value)]` two-way binding, and\r\n * emits the DevExtreme-shaped {@link NxeValueChangedEvent} from `onValueChanged`.\r\n *\r\n * Concrete components MUST register themselves as the value accessor, e.g.:\r\n * ```ts\r\n * @Component({\r\n * selector: 'nxe-text-box',\r\n * providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NxeTextBoxComponent), multi: true }],\r\n * ...\r\n * })\r\n * export class NxeTextBoxComponent extends NxeFormControlBase<string> { ... }\r\n * ```\r\n *\r\n * Subclasses call {@link commitValue} on user interaction and {@link markAsTouched} on blur.\r\n */\r\nlet editorIdCounter = 0;\r\nconst nextEditorId = (): number => ++editorIdCounter;\r\n\r\n/**\r\n * dx size coercion: a bare number (or numeric string) means px, anything else passes through.\r\n * Templates write the attribute form, so the string case is the common one.\r\n */\r\nfunction cssSize(value: number | string | undefined): string | null {\r\n if (value === undefined || value === null || value === '') {\r\n return null;\r\n }\r\n return /^-?\\d+(\\.\\d+)?$/.test(String(value)) ? `${value}px` : String(value);\r\n}\r\n\r\n@Directive({\r\n host: {\r\n '[attr.title]': 'hint() || null',\r\n '[attr.id]': 'elementAttrId()',\r\n '[class]': 'elementAttrClass()',\r\n '[style.width]': 'widthStyle()',\r\n '[style.display]': 'visible() ? null : \"none\"',\r\n // Listened for on the HOST, not on each inner control: these all bubble, so one place\r\n // covers every editor and cannot collide with the handlers an editor already binds on\r\n // its own input.\r\n '(keydown)': 'emitEditorEvent(\"keydown\", $event)',\r\n '(keyup)': 'emitEditorEvent(\"keyup\", $event)',\r\n '(input)': 'emitEditorEvent(\"input\", $event)',\r\n '(change)': 'emitEditorEvent(\"change\", $event)',\r\n '(focusin)': 'emitEditorEvent(\"focusin\", $event)',\r\n '(focusout)': 'emitEditorEvent(\"focusout\", $event)',\r\n '[class.nxe-disabled]': 'disabled()',\r\n '[class.nxe-readonly]': 'readOnly()',\r\n // dx emits `nxe-state-readonly` on a read-only editor, and legacy stylesheets lean on it\r\n // for more than a cursor: the grid's editable-cell tint is keyed off its ABSENCE\r\n // (`td:has(nxe-select-box):not(:has(.dx-state-readonly))`), so a missing class silently\r\n // paints every read-only cell as editable. One binding here covers all eight editors.\r\n '[class.nxe-state-readonly]': 'readOnly()',\r\n },\r\n})\r\nexport abstract class NxeFormControlBase<T> implements ControlValueAccessor, NxeValidationTarget {\r\n protected readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\r\n /**\r\n * The app is zone-based (`provideZoneChangeDetection()`); writing back to Angular forms\r\n * from a signal context must run inside the zone or reactive forms lag a tick.\r\n */\r\n protected readonly ngZone = inject(NgZone);\r\n /** Application-wide defaults; each editor resolves `binding ?? this ?? literal`. */\r\n protected readonly nxeDefaults = inject(NXE_DEFAULT_OPTIONS);\r\n\r\n /**\r\n * The current value — single source of truth. Two-way bindable as `[(value)]` (DevExtreme\r\n * parity) and also driven by `writeValue` for `ngModel`/`formControlName`.\r\n */\r\n readonly value = model<T | null>(null);\r\n\r\n /** Disabled via the `[disabled]` input (DevExtreme parity); OR-combined with forms disabled. */\r\n readonly disabledInput = input(false, { alias: 'disabled', transform: booleanAttribute });\r\n private readonly disabledByForm = signal(false);\r\n /** Effective disabled state (input OR reactive-forms `setDisabledState`). */\r\n readonly disabled = computed(() => this.disabledInput() || this.disabledByForm());\r\n\r\n /** Read-only state (DevExtreme `[readOnly]`). */\r\n readonly readOnly = input(false, { transform: booleanAttribute });\r\n\r\n /** Validation group this editor belongs to (its nested `nxe-validator` registers here). */\r\n readonly validationGroupInput = input<string | undefined>(undefined, { alias: 'validationGroup' });\r\n\r\n /**\r\n * `id` for the INNER control, not the host.\r\n *\r\n * A caption written as `<label for=\"x\">` has to reach the focusable element, and the host of\r\n * a custom element is not it. Without this an editor cannot be labelled at all, which is why\r\n * `aria-label` sits beside it: one of the two has to be available.\r\n */\r\n readonly inputId = input<string | undefined>(undefined);\r\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\r\n readonly ariaLabelledBy = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\r\n\r\n /** Stable per instance, so the inner control always has an id something can point at. */\r\n private readonly fallbackId = `nxe-editor-${nextEditorId()}`;\r\n\r\n readonly controlId = computed(() => this.inputId() ?? this.fallbackId);\r\n\r\n /**\r\n * Ids for a popup listbox and its options.\r\n *\r\n * `aria-activedescendant` is how a combobox says which option is current while focus stays in\r\n * the text field, and it can only point at an id — so the options need stable ones.\r\n */\r\n panelId(): string {\r\n return `${this.controlId()}-panel`;\r\n }\r\n\r\n optionId(index: number): string {\r\n return `${this.controlId()}-option-${index}`;\r\n }\r\n\r\n /**\r\n * Whether a nested validator carries a `required` rule.\r\n *\r\n * Set by the validator rather than declared on the editor: the rule is where the requirement\r\n * is actually stated, and duplicating it as an input would let the two disagree.\r\n */\r\n readonly required = signal(false);\r\n\r\n setRequired(value: boolean): void {\r\n this.required.set(value);\r\n }\r\n\r\n /** The current validation error message (set by a nested `nxe-validator`), or null. */\r\n readonly validationError = signal<string | null>(null);\r\n\r\n /** Whether the control has been blurred at least once. */\r\n readonly touched = signal(false);\r\n /** Whether the value has been changed by the user at least once. */\r\n readonly dirty = signal(false);\r\n\r\n /** DevExtreme-compatible value-change event. */\r\n readonly onValueChanged = output<NxeValueChangedEvent<T>>();\r\n\r\n /**\r\n * dx's keyboard, focus and input events.\r\n *\r\n * Native events already reach the host, so these are not about capability — they are about\r\n * the call site. A migrated `(onEnterKey)` handler should keep working without being\r\n * rewritten as a `(keydown)` with a key check, and `onEnterKey` in particular has no native\r\n * equivalent at all.\r\n */\r\n readonly onKeyDown = output<NxeEditorEvent>();\r\n readonly onKeyUp = output<NxeEditorEvent>();\r\n readonly onEnterKey = output<NxeEditorEvent>();\r\n readonly onInput = output<NxeEditorEvent>();\r\n readonly onChange = output<NxeEditorEvent>();\r\n readonly onFocusIn = output<NxeEditorEvent>();\r\n readonly onFocusOut = output<NxeEditorEvent>();\r\n\r\n /**\r\n * When a typed value is committed: dx's `'change'` (on blur), `'input'` (per keystroke) or\r\n * `'keyup'`.\r\n *\r\n * Honoured by the text editors. The number and date boxes stay on `'change'` whatever this\r\n * says, because their displayed text is derived from the parsed value: committing mid-entry\r\n * would rewrite the field while the user is still typing into it.\r\n */\r\n readonly valueChangeEvent = input<'change' | 'input' | 'keyup'>('change');\r\n\r\n /** dx universal widget options. */\r\n readonly hint = input<string | undefined>(undefined);\r\n readonly width = input<number | string | undefined>(undefined);\r\n readonly visible = input(true, { transform: booleanAttribute });\r\n readonly tabIndex = input<number | undefined>(undefined);\r\n readonly elementAttr = input<Record<string, string> | undefined>(undefined);\r\n\r\n protected readonly widthStyle = computed(() => cssSize(this.width()));\r\n protected readonly elementAttrClass = computed(() => this.elementAttr()?.['class'] ?? null);\r\n protected readonly elementAttrId = computed(() => this.elementAttr()?.['id'] ?? null);\r\n\r\n private _onChange: (value: T | null) => void = () => {};\r\n private _onTouched: () => void = () => {};\r\n\r\n /** Host element (the DevExtreme event payload `element`). */\r\n get element(): HTMLElement {\r\n return this.elementRef.nativeElement;\r\n }\r\n\r\n // --- NxeValidationTarget (consumed by a nested nxe-validator) ---\r\n\r\n getValue(): unknown {\r\n return this.value();\r\n }\r\n\r\n validationGroup(): string | undefined {\r\n return this.validationGroupInput();\r\n }\r\n\r\n setValidationError(message: string | null): void {\r\n this.validationError.set(message);\r\n }\r\n\r\n // --- ControlValueAccessor: forms -> component (no event emission) ---\r\n\r\n writeValue(value: T | null): void {\r\n this.value.set(value);\r\n }\r\n\r\n registerOnChange(fn: (value: T | null) => void): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this.disabledByForm.set(isDisabled);\r\n }\r\n\r\n // --- component -> forms (user interaction) ---\r\n\r\n /**\r\n * Commit a user-initiated value change: update the value, notify Angular forms (inside\r\n * `NgZone.run` so reactive forms detect it in this zone-based app), and emit the\r\n * DevExtreme-shaped `onValueChanged`. No-op when the value is unchanged.\r\n */\r\n protected commitValue(next: T | null, event: Event | null = null): void {\r\n const previousValue = this.value();\r\n if (Object.is(previousValue, next)) {\r\n return;\r\n }\r\n this.value.set(next);\r\n this.dirty.set(true);\r\n this.ngZone.run(() => this._onChange(next));\r\n this.onValueChanged.emit({\r\n value: next,\r\n previousValue,\r\n event,\r\n component: this,\r\n element: this.element,\r\n });\r\n }\r\n\r\n /**\r\n * Re-emit a native event in dx's shape.\r\n *\r\n * `onEnterKey` is the one that earns its keep: it has no native equivalent, so every call\r\n * site would otherwise carry its own key check.\r\n */\r\n protected emitEditorEvent(kind: NxeEditorEventKind, event: Event): void {\r\n const payload: NxeEditorEvent = { event, component: this, element: this.element };\r\n switch (kind) {\r\n case 'keydown':\r\n this.onKeyDown.emit(payload);\r\n if ((event as KeyboardEvent).key === 'Enter') {\r\n this.onEnterKey.emit(payload);\r\n }\r\n break;\r\n case 'keyup':\r\n this.onKeyUp.emit(payload);\r\n break;\r\n case 'input':\r\n this.onInput.emit(payload);\r\n break;\r\n case 'change':\r\n this.onChange.emit(payload);\r\n break;\r\n case 'focusin':\r\n this.onFocusIn.emit(payload);\r\n break;\r\n case 'focusout':\r\n this.onFocusOut.emit(payload);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Commit `next` if `valueChangeEvent` says this is the moment.\r\n *\r\n * Blur always commits, whatever the mode: a value the user typed and then left must not be\r\n * discarded because the configured event never fired.\r\n */\r\n protected commitOn(kind: 'input' | 'keyup' | 'change', next: T | null, event: Event): void {\r\n if (kind === 'change' || this.valueChangeEvent() === kind) {\r\n this.commitValue(next, event);\r\n }\r\n }\r\n\r\n /** Mark the control as touched (e.g. on blur), notifying Angular forms exactly once. */\r\n protected markAsTouched(): void {\r\n if (this.touched()) {\r\n return;\r\n }\r\n this.touched.set(true);\r\n this.ngZone.run(() => this._onTouched());\r\n }\r\n}\r\n","import { Directive } from '@angular/core';\r\nimport { NxeConfigOption } from '../tokens/nxe-config-option.token';\r\n\r\n/**\r\n * Base for no-template nested-option components (see {@link NxeConfigOption}).\r\n *\r\n * Concrete options extend this, declare their inputs as signals, implement {@link nxeConfig}\r\n * (typically returning a `computed()` of those inputs), and register the {@link NXE_OPTION}\r\n * token so the parent can collect them:\r\n * ```ts\r\n * @Component({\r\n * selector: 'nxe-selection',\r\n * template: '',\r\n * providers: [{ provide: NXE_OPTION, useExisting: forwardRef(() => NxeSelectionComponent), multi: true }],\r\n * })\r\n * export class NxeSelectionComponent extends NxeConfigOptionBase<SelectionConfig> {\r\n * readonly nxeRole = 'selection';\r\n * readonly mode = input<'single' | 'multiple'>('single');\r\n * nxeConfig() { return { mode: this.mode() }; }\r\n * }\r\n * ```\r\n */\r\n@Directive()\r\nexport abstract class NxeConfigOptionBase<TConfig> implements NxeConfigOption<TConfig> {\r\n abstract readonly nxeRole: string;\r\n abstract nxeConfig(): TConfig;\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\n/**\r\n * Contract implemented by every flat `nxe-` nested-option component\r\n * (`nxe-column`, `nxe-selection`, `nxe-paging`, `nxe-summary`, `nxe-validation-rule`, ...).\r\n *\r\n * Nested options carry no template; they exist purely to declare configuration. Each one\r\n * exposes its current config as a signal-readable function and a `role` discriminator, so a\r\n * parent (`nxe-data-grid`, `nxe-select-box`, ...) can collect them via `contentChildren` and\r\n * derive a reactive config model — the mechanism that lets\r\n * `<nxe-data-grid><nxe-column/></nxe-data-grid>` mirror `<dx-data-grid><dxi-column/>`.\r\n */\r\nexport interface NxeConfigOption<TConfig = unknown> {\r\n /** Discriminator identifying the option kind, e.g. `'column'`, `'selection'`, `'paging'`. */\r\n readonly nxeRole: string;\r\n /** Returns the option's current configuration (reads signals; recomputes reactively). */\r\n nxeConfig(): TConfig;\r\n}\r\n\r\n/**\r\n * DI token every nested-option component provides (`multi: true`) so parents can query all\r\n * options with `contentChildren(NXE_OPTION)` without importing the concrete option classes.\r\n */\r\nexport const NXE_OPTION = new InjectionToken<NxeConfigOption>('NXE_OPTION');\r\n","import { computed, Directive, inject, input, TemplateRef } from '@angular/core';\r\n\r\n/**\r\n * `nxeTemplate` — drop-in replacement for DevExtreme's `*dxTemplate`.\r\n *\r\n * Captures a named `ng-template` so a parent container (select-box item template, grid\r\n * cell/header/edit templates, list item template, ...) can look it up by name and render it\r\n * with a context object. BOTH authoring forms resolve to the same {@link name}:\r\n *\r\n * - attribute form: `<ng-template nxeTemplate=\"cellContent\" let-data>` (psak-web style)\r\n * - dx microsyntax: `<div *nxeTemplate=\"let data of 'cellContent'\">` — desugars the name into\r\n * an `nxeTemplateOf` binding (orbit's mechanically-migrated `*dxTemplate` templates)\r\n *\r\n * Parents collect these via `contentChildren(NxeTemplateDirective)` and match on {@link name},\r\n * rendering with `ngTemplateOutlet` + an `ngTemplateOutletContext` of `{ $implicit: data, ... }`.\r\n */\r\n@Directive({\r\n selector: '[nxeTemplate]',\r\n})\r\nexport class NxeTemplateDirective {\r\n /** Attribute-form name (`nxeTemplate=\"name\"`); empty in microsyntax usage. */\r\n readonly attrName = input<string>('', { alias: 'nxeTemplate' });\r\n /** Microsyntax-form name (`*nxeTemplate=\"let x of 'name'\"` binds `nxeTemplateOf`). */\r\n readonly ofName = input<string | undefined>(undefined, { alias: 'nxeTemplateOf' });\r\n\r\n /** The template's lookup name, whichever form supplied it. */\r\n readonly name = computed(() => this.ofName() ?? this.attrName());\r\n\r\n readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);\r\n}\r\n","/**\r\n * Wrap a value in an array if it is not already one (null/undefined -> empty array).\r\n *\r\n * Mirrors `@angular/cdk/coercion`'s `coerceArray` so nxe components don't import CDK coercion\r\n * directly. (For boolean/number coercion use `booleanAttribute` / `numberAttribute` from\r\n * `@angular/core` directly on `input(...)`.)\r\n */\r\nexport function coerceArray<T>(value: T | readonly T[] | null | undefined): T[] {\r\n if (value == null) {\r\n return [];\r\n }\r\n return Array.isArray(value) ? [...value] : [value as T];\r\n}\r\n","import { booleanAttribute } from '@angular/core';\r\n\r\n/**\r\n * `booleanAttribute` that preserves \"unset\".\r\n *\r\n * An input resolved as `binding ?? token ?? literal` needs three states, but\r\n * `booleanAttribute` has two: it maps `undefined` to `false`, which makes \"nobody bound this\"\r\n * indistinguishable from \"someone bound false\" and silently removes the token rung.\r\n *\r\n * This keeps the attribute-form coercion (`showClearButton=\"false\"` is `false`, not the truthy\r\n * string) and passes `undefined` straight through.\r\n */\r\nexport function nxeOptionalBoolean(value: unknown): boolean | undefined {\r\n return value === undefined || value === null ? undefined : booleanAttribute(value);\r\n}\r\n","/**\r\n * DevExtreme's `displayExpr` / `valueExpr` / `searchExpr` accessor.\r\n *\r\n * dx accepts four spellings and the library accepted one — a flat property name — so a dotted\r\n * path silently read `item['user.name']` and returned undefined. Silent, because an accessor\r\n * that misses looks exactly like a field that is empty.\r\n *\r\n * undefined / '' the item itself (dx: no expression)\r\n * 'this' the item itself (dx's documented sentinel)\r\n * 'user.name' a dotted path\r\n * (item) => ... a function accessor\r\n */\r\nexport type NxeExpr<T = unknown> = string | ((item: T) => unknown) | undefined | null;\r\n\r\n/** Resolve `expr` against `item`. */\r\nexport function nxeResolveExpr<T = unknown>(expr: NxeExpr<T>, item: T): unknown {\r\n if (typeof expr === 'function') {\r\n return expr(item);\r\n }\r\n if (!expr || expr === 'this') {\r\n return item;\r\n }\r\n if (item == null || typeof item !== 'object') {\r\n return undefined;\r\n }\r\n if (!expr.includes('.')) {\r\n return (item as Record<string, unknown>)[expr];\r\n }\r\n return expr\r\n .split('.')\r\n .reduce<unknown>(\r\n (acc, key) => (acc == null || typeof acc !== 'object' ? undefined : (acc as Record<string, unknown>)[key]),\r\n item,\r\n );\r\n}\r\n\r\n/** Resolve `expr` and render it as display text: `null`/`undefined` become the empty string. */\r\nexport function nxeResolveText<T = unknown>(expr: NxeExpr<T>, item: T): string {\r\n const resolved = nxeResolveExpr(expr, item);\r\n return resolved == null ? '' : String(resolved);\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\n/** A single failed validation rule. */\r\nexport interface NxeBrokenRule {\r\n type: string;\r\n message: string;\r\n}\r\n\r\n/**\r\n * Result of validating a control or a validation group — shaped to match\r\n * DevExtreme's `ValidationGroup.validate()` / `dxValidator.validate()` return value so existing\r\n * handlers (`const r = event.validationGroup.validate(); if (r.isValid) {...}`) work unchanged.\r\n */\r\nexport interface NxeValidationResult {\r\n isValid: boolean;\r\n brokenRules: NxeBrokenRule[];\r\n status: 'valid' | 'invalid' | 'pending';\r\n}\r\n\r\n/**\r\n * Contract an editor exposes (via {@link NXE_VALIDATION_TARGET}) to the `nxe-validator` nested\r\n * inside it: read the current value, the editor's validation group, and push the invalid\r\n * message back so the editor can render it.\r\n */\r\nexport interface NxeValidationTarget {\r\n getValue(): unknown;\r\n validationGroup(): string | undefined;\r\n setValidationError(message: string | null): void;\r\n /**\r\n * Tell the editor whether a `required` rule applies, so it can render `aria-required`.\r\n * Optional: a target predating this simply does not advertise the requirement.\r\n */\r\n setRequired?(required: boolean): void;\r\n}\r\n\r\n/** DI token the editor provides so its nested `nxe-validator` can adapt it. */\r\nexport const NXE_VALIDATION_TARGET = new InjectionToken<NxeValidationTarget>(\r\n 'NXE_VALIDATION_TARGET',\r\n);\r\n\r\n/** A member registered in a validation group (an `nxe-validator`). */\r\nexport interface NxeValidationGroupMember {\r\n validate(): NxeValidationResult;\r\n /** Clear the member's error state without validating. Optional for older members. */\r\n reset?(): void;\r\n}\r\n\r\n/**\r\n * An `nxe-validation-group` ancestor, exposed so a validator or a button inside it can join it\r\n * without naming a group.\r\n *\r\n * DevExtreme lets a group be addressed two ways: by a string name shared between a validator and\r\n * a button, or structurally by wrapping both in a `dxValidationGroup`. The string form is what\r\n * the consuming applications use; this token is the structural one, and an explicit string\r\n * always wins over it, as in dx.\r\n */\r\nexport interface NxeValidationGroupScope {\r\n /** Opaque, unique per instance — never collides with an application's own group names. */\r\n readonly groupKey: string;\r\n}\r\n\r\nexport const NXE_VALIDATION_GROUP = new InjectionToken<NxeValidationGroupScope>(\r\n 'NXE_VALIDATION_GROUP',\r\n);\r\n\r\n/** DevExtreme-shaped `onValidated` payload. */\r\nexport interface NxeValidatedEvent extends NxeValidationResult {\r\n value: unknown;\r\n validationGroup: string;\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { NxeBrokenRule, NxeValidationGroupMember, NxeValidationResult } from './nxe-validation.types';\r\n\r\n/**\r\n * Root registry mapping a `validationGroup` string to the `nxe-validator`s in it, mirroring\r\n * DevExtreme's global ValidationEngine.\r\n *\r\n * `nxe-button[validationGroup]` (and any caller) triggers {@link validate} for a group, which\r\n * runs every member validator and aggregates the result into the DevExtreme-shaped\r\n * {@link NxeValidationResult}.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class NxeValidationGroupRegistry {\r\n private readonly groups = new Map<string, Set<NxeValidationGroupMember>>();\r\n\r\n register(group: string, member: NxeValidationGroupMember): void {\r\n let set = this.groups.get(group);\r\n if (!set) {\r\n set = new Set();\r\n this.groups.set(group, set);\r\n }\r\n set.add(member);\r\n }\r\n\r\n unregister(group: string, member: NxeValidationGroupMember): void {\r\n const set = this.groups.get(group);\r\n if (!set) {\r\n return;\r\n }\r\n set.delete(member);\r\n if (set.size === 0) {\r\n this.groups.delete(group);\r\n }\r\n }\r\n\r\n /**\r\n * Clear every member's error state without validating.\r\n *\r\n * dx's `ValidationGroup.reset()`. The distinction from `validate()` matters after a Cancel:\r\n * the fields should stop showing errors, not be re-checked and light up again.\r\n */\r\n reset(group: string): void {\r\n for (const member of this.groups.get(group) ?? []) {\r\n member.reset?.();\r\n }\r\n }\r\n\r\n /** Validate every member of the group; valid (and empty) groups return `isValid: true`. */\r\n validate(group: string): NxeValidationResult {\r\n const set = this.groups.get(group);\r\n const brokenRules: NxeBrokenRule[] = [];\r\n if (set) {\r\n for (const member of set) {\r\n const result = member.validate();\r\n if (!result.isValid) {\r\n brokenRules.push(...result.brokenRules);\r\n }\r\n }\r\n }\r\n return {\r\n isValid: brokenRules.length === 0,\r\n brokenRules,\r\n status: brokenRules.length === 0 ? 'valid' : 'invalid',\r\n };\r\n }\r\n}\r\n","// @nexterajs/ui — core abstractions shared by every component.\r\n\r\nexport * from './types/nxe-events';\r\nexport * from './base/nxe-form-control.base';\r\nexport * from './base/nxe-config-option.base';\r\nexport * from './tokens/nxe-config-option.token';\r\nexport * from './tokens/nxe-default-options.token';\r\nexport * from './directives/nxe-template.directive';\r\nexport * from './coercion/coerce-array';\r\nexport * from './coercion/optional-boolean';\r\nexport * from './coercion/nxe-expr';\r\nexport * from './validation/nxe-validation.types';\r\nexport * from './validation/nxe-validation-group-registry.service';\r\n","// @nexterajs/ui/core — public API.\r\nexport * from './lib/core/index';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|