@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.
Files changed (44) hide show
  1. package/fesm2022/nexterajs-ui-core.mjs +189 -5
  2. package/fesm2022/nexterajs-ui-core.mjs.map +1 -1
  3. package/fesm2022/nexterajs-ui-dropdowns.mjs +314 -50
  4. package/fesm2022/nexterajs-ui-dropdowns.mjs.map +1 -1
  5. package/fesm2022/nexterajs-ui-file-uploader.mjs +6 -3
  6. package/fesm2022/nexterajs-ui-file-uploader.mjs.map +1 -1
  7. package/fesm2022/nexterajs-ui-forms.mjs +729 -370
  8. package/fesm2022/nexterajs-ui-forms.mjs.map +1 -1
  9. package/fesm2022/nexterajs-ui-grid.mjs +1188 -208
  10. package/fesm2022/nexterajs-ui-grid.mjs.map +1 -1
  11. package/fesm2022/nexterajs-ui-intl.mjs +15 -5
  12. package/fesm2022/nexterajs-ui-intl.mjs.map +1 -1
  13. package/fesm2022/nexterajs-ui-notify.mjs +351 -0
  14. package/fesm2022/nexterajs-ui-notify.mjs.map +1 -0
  15. package/fesm2022/nexterajs-ui-pivot.mjs +146 -116
  16. package/fesm2022/nexterajs-ui-pivot.mjs.map +1 -1
  17. package/fesm2022/nexterajs-ui-styling.mjs +568 -3
  18. package/fesm2022/nexterajs-ui-styling.mjs.map +1 -1
  19. package/fesm2022/nexterajs-ui-tree-view.mjs +147 -18
  20. package/fesm2022/nexterajs-ui-tree-view.mjs.map +1 -1
  21. package/fesm2022/nexterajs-ui-validation.mjs +247 -92
  22. package/fesm2022/nexterajs-ui-validation.mjs.map +1 -1
  23. package/fesm2022/nexterajs-ui.mjs +1 -0
  24. package/fesm2022/nexterajs-ui.mjs.map +1 -1
  25. package/package.json +5 -1
  26. package/styles/_dropdown.scss +149 -0
  27. package/styles/_editor.scss +23 -4
  28. package/styles/_icons.scss +92 -0
  29. package/styles/_mixins.scss +104 -1
  30. package/styles/_scrollbar.scss +134 -0
  31. package/styles/_toast.scss +243 -0
  32. package/styles/_tokens.scss +48 -0
  33. package/styles/index.scss +4 -0
  34. package/types/nexterajs-ui-core.d.ts +142 -22
  35. package/types/nexterajs-ui-dropdowns.d.ts +145 -27
  36. package/types/nexterajs-ui-file-uploader.d.ts +4 -1
  37. package/types/nexterajs-ui-forms.d.ts +103 -19
  38. package/types/nexterajs-ui-grid.d.ts +445 -57
  39. package/types/nexterajs-ui-notify.d.ts +147 -0
  40. package/types/nexterajs-ui-pivot.d.ts +35 -22
  41. package/types/nexterajs-ui-styling.d.ts +163 -3
  42. package/types/nexterajs-ui-tree-view.d.ts +50 -1
  43. package/types/nexterajs-ui-validation.d.ts +94 -15
  44. 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.dx-state-readonly": "readOnly()" } }, ngImport: i0 });
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 `dx-state-readonly` on a read-only editor, and legacy stylesheets lean on it
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.dx-state-readonly]': 'readOnly()',
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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"}