@ajf/material 18.4.0 → 18.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +167 -2
  2. package/audio/src/audio-module.d.ts +7 -6
  3. package/esm2022/audio/src/audio-module.mjs +22 -4
  4. package/esm2022/audio/src/audio.mjs +6 -6
  5. package/esm2022/barcode/barcode.mjs +3 -3
  6. package/esm2022/calendar/calendar.mjs +2 -2
  7. package/esm2022/checkbox-group/checkbox-group-item.mjs +3 -3
  8. package/esm2022/form-builder/form-builder-module.mjs +9 -2
  9. package/esm2022/form-builder/form-builder-service.mjs +63 -20
  10. package/esm2022/form-builder/form-builder.mjs +73 -9
  11. package/esm2022/form-builder/node-entry.mjs +3 -3
  12. package/esm2022/form-builder/node-properties.mjs +3 -13
  13. package/esm2022/form-builder/node-type-entry.mjs +3 -3
  14. package/esm2022/form-builder/node-type-groups.pipe.mjs +65 -0
  15. package/esm2022/form-builder/public_api.mjs +2 -1
  16. package/esm2022/form-builder/string-identifier-dialog.mjs +44 -60
  17. package/esm2022/forms/boolean-field.mjs +6 -5
  18. package/esm2022/forms/current-slide.mjs +92 -0
  19. package/esm2022/forms/date-input-field.mjs +7 -9
  20. package/esm2022/forms/display-field.mjs +2 -2
  21. package/esm2022/forms/empty-field.mjs +3 -3
  22. package/esm2022/forms/field-row.mjs +117 -0
  23. package/esm2022/forms/field.mjs +2 -2
  24. package/esm2022/forms/form.mjs +107 -13
  25. package/esm2022/forms/forms-module.mjs +26 -3
  26. package/esm2022/forms/input-field.mjs +6 -8
  27. package/esm2022/forms/multiple-choice-field.mjs +45 -10
  28. package/esm2022/forms/public_api.mjs +6 -1
  29. package/esm2022/forms/range-field.mjs +5 -6
  30. package/esm2022/forms/rep-strip.mjs +61 -0
  31. package/esm2022/forms/single-choice-field.mjs +26 -11
  32. package/esm2022/forms/slide-header.mjs +68 -0
  33. package/esm2022/forms/slide-stats.mjs +148 -0
  34. package/esm2022/forms/table-field.mjs +2 -2
  35. package/esm2022/forms/text-field.mjs +2 -2
  36. package/esm2022/forms/video-url-field.mjs +6 -8
  37. package/esm2022/geolocation/geolocation.mjs +4 -6
  38. package/esm2022/page-slider/page-slider.mjs +3 -3
  39. package/esm2022/signature/signature.mjs +5 -6
  40. package/esm2022/time/time-module.mjs +22 -4
  41. package/esm2022/time/time.mjs +4 -4
  42. package/fesm2022/ajf-material-audio.mjs +27 -9
  43. package/fesm2022/ajf-material-audio.mjs.map +1 -1
  44. package/fesm2022/ajf-material-barcode.mjs +2 -2
  45. package/fesm2022/ajf-material-barcode.mjs.map +1 -1
  46. package/fesm2022/ajf-material-calendar.mjs +2 -2
  47. package/fesm2022/ajf-material-calendar.mjs.map +1 -1
  48. package/fesm2022/ajf-material-checkbox-group.mjs +2 -2
  49. package/fesm2022/ajf-material-checkbox-group.mjs.map +1 -1
  50. package/fesm2022/ajf-material-form-builder.mjs +260 -108
  51. package/fesm2022/ajf-material-form-builder.mjs.map +1 -1
  52. package/fesm2022/ajf-material-forms.mjs +712 -99
  53. package/fesm2022/ajf-material-forms.mjs.map +1 -1
  54. package/fesm2022/ajf-material-geolocation.mjs +5 -7
  55. package/fesm2022/ajf-material-geolocation.mjs.map +1 -1
  56. package/fesm2022/ajf-material-page-slider.mjs +2 -2
  57. package/fesm2022/ajf-material-page-slider.mjs.map +1 -1
  58. package/fesm2022/ajf-material-signature.mjs +7 -8
  59. package/fesm2022/ajf-material-signature.mjs.map +1 -1
  60. package/fesm2022/ajf-material-time.mjs +24 -6
  61. package/fesm2022/ajf-material-time.mjs.map +1 -1
  62. package/form-builder/form-builder-module.d.ts +27 -25
  63. package/form-builder/form-builder-service.d.ts +25 -0
  64. package/form-builder/form-builder.d.ts +41 -2
  65. package/form-builder/node-type-groups.pipe.d.ts +45 -0
  66. package/form-builder/public_api.d.ts +1 -0
  67. package/form-builder/string-identifier-dialog.d.ts +10 -16
  68. package/forms/_theming.scss +142 -0
  69. package/forms/current-slide.d.ts +61 -0
  70. package/forms/field-row.d.ts +63 -0
  71. package/forms/form.d.ts +40 -3
  72. package/forms/forms-module.d.ts +57 -51
  73. package/forms/multiple-choice-field.d.ts +15 -1
  74. package/forms/public_api.d.ts +5 -0
  75. package/forms/rep-strip.d.ts +52 -0
  76. package/forms/single-choice-field.d.ts +7 -0
  77. package/forms/slide-header.d.ts +61 -0
  78. package/forms/slide-stats.d.ts +76 -0
  79. package/package.json +2 -2
  80. package/time/time-module.d.ts +4 -3
@@ -1,27 +1,24 @@
1
- import * as i1 from '@ajf/core/forms';
2
- import { AjfBaseFieldComponent, AJF_WARNING_ALERT_SERVICE, AjfAudioFieldComponent as AjfAudioFieldComponent$1, AjfInputFieldComponent as AjfInputFieldComponent$1, AjfFieldWithChoicesComponent, AJF_SEARCH_ALERT_THRESHOLD, AjfTableFieldComponent as AjfTableFieldComponent$1, AjfVideoUrlFieldComponent as AjfVideoUrlFieldComponent$1, AjfFieldService as AjfFieldService$1, AjfReadOnlyFieldComponent, AjfFieldType, AjfReadOnlyDateFieldComponent, AjfReadOnlyTableFieldComponent, AjfReadOnlySelectFieldComponent, AjfReadOnlyImageFieldComponent, AjfReadOnlyGeolocationFieldComponent, AjfReadOnlyFileFieldComponent, AjfFileFieldComponent, AjfImageFieldComponent, AjfReadOnlyVideoUrlFieldComponent, AjfFormField as AjfFormField$1, AjfFormRenderer as AjfFormRenderer$1, AjfFormsModule as AjfFormsModule$1 } from '@ajf/core/forms';
1
+ import * as i1$1 from '@ajf/core/forms';
2
+ import { AjfBaseFieldComponent, AJF_WARNING_ALERT_SERVICE, isRepeatingSlideInstance, AjfAudioFieldComponent as AjfAudioFieldComponent$1, AjfInputFieldComponent as AjfInputFieldComponent$1, AjfFieldWithChoicesComponent, AJF_SEARCH_ALERT_THRESHOLD, AjfTableFieldComponent as AjfTableFieldComponent$1, AjfVideoUrlFieldComponent as AjfVideoUrlFieldComponent$1, AjfFieldService as AjfFieldService$1, AjfReadOnlyFieldComponent, AjfFieldType, AjfReadOnlyDateFieldComponent, AjfReadOnlyTableFieldComponent, AjfReadOnlySelectFieldComponent, AjfReadOnlyImageFieldComponent, AjfReadOnlyGeolocationFieldComponent, AjfReadOnlyFileFieldComponent, AjfFileFieldComponent, AjfImageFieldComponent, AjfReadOnlyVideoUrlFieldComponent, AjfFormField as AjfFormField$1, AjfNodeType, isFieldInstance, nodeInstanceCompleteName, AjfFormRenderer as AjfFormRenderer$1, AjfFormsModule as AjfFormsModule$1 } from '@ajf/core/forms';
3
3
  import * as i0 from '@angular/core';
4
- import { ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable, Inject, ViewChild, Optional, Input, NgModule } from '@angular/core';
4
+ import { ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable, Inject, Pipe, ViewChild, Optional, HostBinding, Input, EventEmitter, Output, NgModule } from '@angular/core';
5
5
  import * as i2$1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
7
  import * as i3 from '@angular/material/slide-toggle';
8
8
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
9
9
  import * as i4 from '@angular/forms';
10
10
  import { FormControl, ReactiveFormsModule } from '@angular/forms';
11
+ import * as i5 from '@ngneat/transloco';
11
12
  import { map, switchMap, startWith, distinctUntilChanged, debounceTime } from 'rxjs/operators';
12
- import * as i5 from '@angular/material/button';
13
+ import * as i1 from '@angular/material/button';
13
14
  import { MatButtonModule } from '@angular/material/button';
14
15
  import * as i2 from '@angular/material/dialog';
15
16
  import { MatDialogModule } from '@angular/material/dialog';
16
17
  import * as i2$2 from '@ajf/material/calendar';
17
18
  import { AjfCalendarModule } from '@ajf/material/calendar';
18
- import * as i6 from '@angular/material/input';
19
19
  import { MatInput, MatInputModule } from '@angular/material/input';
20
20
  import * as i4$1 from '@angular/material/datepicker';
21
21
  import { MatDatepickerModule } from '@angular/material/datepicker';
22
- import * as i5$1 from '@angular/material/form-field';
23
- import { MatFormFieldModule } from '@angular/material/form-field';
24
- import * as i8 from '@ngneat/transloco';
25
22
  import * as i2$3 from '@ajf/material/audio';
26
23
  import { AjfAudioModule } from '@ajf/material/audio';
27
24
  import * as i2$4 from '@ajf/material/barcode';
@@ -30,44 +27,44 @@ import * as i4$2 from '@ajf/core/common';
30
27
  import { AjfCommonModule } from '@ajf/core/common';
31
28
  import * as i2$5 from '@ajf/material/geolocation';
32
29
  import { AjfGeolocationModule } from '@ajf/material/geolocation';
33
- import { Subject, Subscription, of, combineLatest, merge } from 'rxjs';
30
+ import { Subject, Subscription, of, combineLatest, merge, EMPTY } from 'rxjs';
34
31
  import * as i2$6 from '@ajf/material/checkbox-group';
35
32
  import { AjfCheckboxGroupModule } from '@ajf/material/checkbox-group';
36
33
  import * as i3$1 from '@ajf/core/checkbox-group';
37
- import * as i5$2 from '@angular/material/select';
34
+ import * as i2$7 from '@angular/material/icon';
35
+ import { MatIconModule } from '@angular/material/icon';
36
+ import * as i6 from '@angular/material/select';
38
37
  import { MatSelectModule } from '@angular/material/select';
39
- import * as i6$1 from '@angular/material/core';
38
+ import * as i7 from '@angular/material/core';
40
39
  import { MatNativeDateModule } from '@angular/material/core';
41
- import * as i8$1 from 'ngx-mat-select-search';
40
+ import * as i9 from 'ngx-mat-select-search';
42
41
  import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
43
42
  import { AjfRange } from '@ajf/core/range';
44
- import * as i3$2 from '@angular/material/icon';
45
- import { MatIconModule } from '@angular/material/icon';
46
- import * as i5$3 from '@angular/material/slider';
43
+ import * as i5$1 from '@angular/material/slider';
47
44
  import { MatSliderModule } from '@angular/material/slider';
48
- import * as i3$3 from '@angular/material/radio';
49
- import { MatRadioModule } from '@angular/material/radio';
50
45
  import * as i4$3 from 'ngx-quill';
51
46
  import { QuillModule } from 'ngx-quill';
52
- import * as i2$7 from '@ajf/material/time';
47
+ import * as i2$8 from '@ajf/material/time';
53
48
  import { AjfTimeModule } from '@ajf/material/time';
54
- import * as i2$8 from '@angular/platform-browser';
55
- import * as i3$4 from '@angular/common/http';
56
- import * as i2$9 from '@ajf/material/signature';
49
+ import * as i2$9 from '@angular/platform-browser';
50
+ import * as i3$2 from '@angular/common/http';
51
+ import * as i2$a from '@ajf/material/signature';
57
52
  import { AjfSignatureModule } from '@ajf/material/signature';
58
- import * as i2$a from '@ajf/core/page-slider';
53
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
54
+ import * as i3$3 from '@angular/material/tooltip';
55
+ import { MatTooltipModule } from '@angular/material/tooltip';
56
+ import * as i2$b from '@ajf/core/page-slider';
59
57
  import * as i3$5 from '@ajf/material/page-slider';
60
58
  import { AjfPageSliderModule } from '@ajf/material/page-slider';
61
- import * as i6$2 from '@angular/material/button-toggle';
59
+ import * as i3$4 from '@angular/material/menu';
60
+ import { MatMenuModule } from '@angular/material/menu';
61
+ import { AjfTranslocoModule } from '@ajf/core/transloco';
62
+ import { TextFieldModule } from '@angular/cdk/text-field';
62
63
  import { MatButtonToggleModule } from '@angular/material/button-toggle';
63
- import * as i7 from '@angular/material/card';
64
64
  import { MatCardModule } from '@angular/material/card';
65
- import * as i9 from '@angular/material/toolbar';
65
+ import { MatFormFieldModule } from '@angular/material/form-field';
66
+ import { MatRadioModule } from '@angular/material/radio';
66
67
  import { MatToolbarModule } from '@angular/material/toolbar';
67
- import * as i10 from '@angular/material/tooltip';
68
- import { MatTooltipModule } from '@angular/material/tooltip';
69
- import { AjfTranslocoModule } from '@ajf/core/transloco';
70
- import { TextFieldModule } from '@angular/cdk/text-field';
71
68
 
72
69
  /**
73
70
  * @license
@@ -95,7 +92,7 @@ class AjfFieldWarningDialog {
95
92
  this.message = '';
96
93
  }
97
94
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFieldWarningDialog, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
98
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfFieldWarningDialog, selector: "ng-component", ngImport: i0, template: "<mat-dialog-content><div [innerHTML]=\"message\"></div></mat-dialog-content>\n<mat-dialog-actions>\n <button mat-button [mat-dialog-close]=\"true\">Ok</button>\n <button mat-button [mat-dialog-close]=\"false\">Cancel</button>\n</mat-dialog-actions>\n", dependencies: [{ kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
95
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfFieldWarningDialog, selector: "ng-component", ngImport: i0, template: "<mat-dialog-content><div [innerHTML]=\"message\"></div></mat-dialog-content>\n<mat-dialog-actions>\n <button mat-button [mat-dialog-close]=\"true\">Ok</button>\n <button mat-button [mat-dialog-close]=\"false\">Cancel</button>\n</mat-dialog-actions>\n", dependencies: [{ kind: "component", type: i1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
99
96
  }
100
97
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFieldWarningDialog, decorators: [{
101
98
  type: Component,
@@ -143,17 +140,106 @@ class AjfBooleanFieldComponent extends AjfBaseFieldComponent {
143
140
  constructor(cdr, service, was) {
144
141
  super(cdr, service, was);
145
142
  }
146
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfBooleanFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
147
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfBooleanFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<mat-slide-toggle *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></mat-slide-toggle>\n", styles: [""], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
143
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfBooleanFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
144
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfBooleanFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <mat-slide-toggle [formControl]=\"ctrl!\"></mat-slide-toggle>\n <span class=\"ajf-bool-label\">{{ (ctrl.value ? 'Yes' : 'No') | transloco }}</span>\n</ng-container>\n", styles: ["ajf-field .ajf-bool-label{color:var(--ajf-text);font-size:14px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
148
145
  }
149
146
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfBooleanFieldComponent, decorators: [{
150
147
  type: Component,
151
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-slide-toggle *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></mat-slide-toggle>\n" }]
152
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
148
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <mat-slide-toggle [formControl]=\"ctrl!\"></mat-slide-toggle>\n <span class=\"ajf-bool-label\">{{ (ctrl.value ? 'Yes' : 'No') | transloco }}</span>\n</ng-container>\n", styles: ["ajf-field .ajf-bool-label{color:var(--ajf-text);font-size:14px}\n"] }]
149
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
153
150
  type: Inject,
154
151
  args: [AJF_WARNING_ALERT_SERVICE]
155
152
  }] }] });
156
153
 
154
+ /**
155
+ * @license
156
+ * Copyright (C) Gnucoop soc. coop.
157
+ *
158
+ * This file is part of the Advanced JSON forms (ajf).
159
+ *
160
+ * Advanced JSON forms (ajf) is free software: you can redistribute it and/or
161
+ * modify it under the terms of the GNU Affero General Public License as
162
+ * published by the Free Software Foundation, either version 3 of the License,
163
+ * or (at your option) any later version.
164
+ *
165
+ * Advanced JSON forms (ajf) is distributed in the hope that it will be useful,
166
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
167
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
168
+ * General Public License for more details.
169
+ *
170
+ * You should have received a copy of the GNU Affero General Public License
171
+ * along with Advanced JSON forms (ajf).
172
+ * If not, see http://www.gnu.org/licenses/.
173
+ *
174
+ */
175
+ const pageCount = (slide) => isRepeatingSlideInstance(slide) ? Math.max(1, slide.reps) : 1;
176
+ /**
177
+ * Resolve the page slider's current page into a slide.
178
+ *
179
+ * The renderer lays out one page per slide, and one page per repetition of a
180
+ * repeating slide, optionally preceded by a start message page -- the same
181
+ * arithmetic the error navigation in `AjfFormRenderer` performs.
182
+ *
183
+ * Impure, because slide visibility and repetition counts are mutated in place.
184
+ * The result is memoized so that the pipe keeps handing back the same object
185
+ * while nothing has moved: returning a fresh one on every check would trip
186
+ * Angular's "expression has changed after it was checked" guard.
187
+ */
188
+ class AjfCurrentSlidePipe {
189
+ constructor() {
190
+ this._last = null;
191
+ }
192
+ transform(slides, currentPage, hasStartMessage, hasEndMessage = false) {
193
+ const visible = (slides || []).filter(s => s.visible !== false);
194
+ const offset = hasStartMessage ? 1 : 0;
195
+ const next = {
196
+ slide: null,
197
+ repIndex: 0,
198
+ reps: 0,
199
+ displayNumber: Math.max(1, (currentPage || 0) + 1),
200
+ total: visible.length,
201
+ pages: offset +
202
+ (hasEndMessage ? 1 : 0) +
203
+ visible.reduce((count, slide) => count + pageCount(slide), 0),
204
+ };
205
+ let page = (currentPage || 0) - offset;
206
+ if (page >= 0) {
207
+ for (let i = 0; i < visible.length; i++) {
208
+ const slide = visible[i];
209
+ const pages = pageCount(slide);
210
+ if (page < pages) {
211
+ next.slide = slide;
212
+ next.repIndex = page;
213
+ next.reps = isRepeatingSlideInstance(slide)
214
+ ? slide.reps
215
+ : 0;
216
+ next.displayNumber = i + 1 + offset;
217
+ break;
218
+ }
219
+ page -= pages;
220
+ }
221
+ }
222
+ const last = this._last;
223
+ if (last != null &&
224
+ last.slide === next.slide &&
225
+ last.repIndex === next.repIndex &&
226
+ last.reps === next.reps &&
227
+ last.displayNumber === next.displayNumber &&
228
+ last.total === next.total &&
229
+ last.pages === next.pages) {
230
+ return last;
231
+ }
232
+ this._last = next;
233
+ return next;
234
+ }
235
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfCurrentSlidePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
236
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AjfCurrentSlidePipe, name: "ajfCurrentSlide", pure: false }); }
237
+ }
238
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfCurrentSlidePipe, decorators: [{
239
+ type: Pipe,
240
+ args: [{ name: 'ajfCurrentSlide', pure: false }]
241
+ }] });
242
+
157
243
  /**
158
244
  * @license
159
245
  * Copyright (C) Gnucoop soc. coop.
@@ -179,13 +265,13 @@ class AjfDateFieldComponent extends AjfBaseFieldComponent {
179
265
  constructor(cdr, service, was) {
180
266
  super(cdr, service, was);
181
267
  }
182
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDateFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
183
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfDateFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ajf-calendar\n *ngIf=\"control|async as ctrl\"\n selectionMode=\"day\"\n [dateOnlyForDay]=\"true\"\n [minDate]=\"instance!.node.minDate|ajfDateValue\"\n [maxDate]=\"instance!.node.maxDate|ajfDateValue\"\n [formControl]=\"ctrl!\"\n></ajf-calendar>\n", styles: [""], dependencies: [{ kind: "component", type: i2$2.AjfCalendarComponent, selector: "ajf-calendar" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.AjfDateValuePipe, name: "ajfDateValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
268
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDateFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
269
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfDateFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ajf-calendar\n *ngIf=\"control|async as ctrl\"\n selectionMode=\"day\"\n [dateOnlyForDay]=\"true\"\n [minDate]=\"instance!.node.minDate|ajfDateValue\"\n [maxDate]=\"instance!.node.maxDate|ajfDateValue\"\n [formControl]=\"ctrl!\"\n></ajf-calendar>\n", styles: [""], dependencies: [{ kind: "component", type: i2$2.AjfCalendarComponent, selector: "ajf-calendar" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.AjfDateValuePipe, name: "ajfDateValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
184
270
  }
185
271
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDateFieldComponent, decorators: [{
186
272
  type: Component,
187
273
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ajf-calendar\n *ngIf=\"control|async as ctrl\"\n selectionMode=\"day\"\n [dateOnlyForDay]=\"true\"\n [minDate]=\"instance!.node.minDate|ajfDateValue\"\n [maxDate]=\"instance!.node.maxDate|ajfDateValue\"\n [formControl]=\"ctrl!\"\n></ajf-calendar>\n" }]
188
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
274
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
189
275
  type: Inject,
190
276
  args: [AJF_WARNING_ALERT_SERVICE]
191
277
  }] }] });
@@ -218,13 +304,13 @@ class AjfDateInputFieldComponent extends AjfBaseFieldComponent {
218
304
  clear(ctrl) {
219
305
  ctrl.setValue(null);
220
306
  }
221
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDateInputFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
222
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfDateInputFieldComponent, selector: "ng-component", viewQueries: [{ propertyName: "input", first: true, predicate: MatInput, descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field *ngIf=\"control|async as ctrl\">\n <input\n matInput\n [matDatepicker]=\"picker\"\n [attr.aria-label]=\"instance!|ajfNodeCompleteName\"\n [min]=\"instance!.node.minDate|ajfDateValueString\"\n [max]=\"instance!.node.maxDate|ajfDateValueString\"\n [formControl]=\"ctrl!\"\n readonly\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker>\n <mat-datepicker-actions>\n <button mat-button (click)=\"clear(ctrl); picker.close()\">{{'Clear'|transloco}}</button>\n <button mat-raised-button color=\"primary\" matDatepickerApply>{{'OK'|transloco}}</button>\n </mat-datepicker-actions>\n </mat-datepicker>\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i4$1.MatDatepickerActions, selector: "mat-datepicker-actions, mat-date-range-picker-actions" }, { kind: "directive", type: i4$1.MatDatepickerApply, selector: "[matDatepickerApply], [matDateRangePickerApply]" }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.AjfDateValueStringPipe, name: "ajfDateValueString" }, { kind: "pipe", type: i1.AjfNodeCompleteNamePipe, name: "ajfNodeCompleteName" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
307
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDateInputFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
308
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfDateInputFieldComponent, selector: "ng-component", viewQueries: [{ propertyName: "input", first: true, predicate: MatInput, descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <span class=\"ajf-input-group ajf-control--mono\">\n <input\n [matDatepicker]=\"picker\"\n [attr.aria-label]=\"instance! | ajfNodeCompleteName\"\n [min]=\"instance!.node.minDate | ajfDateValueString\"\n [max]=\"instance!.node.maxDate | ajfDateValueString\"\n [formControl]=\"ctrl!\"\n readonly\n />\n <mat-datepicker-toggle class=\"ajf-input-group-action\" [for]=\"picker\"></mat-datepicker-toggle>\n </span>\n <mat-datepicker #picker>\n <mat-datepicker-actions>\n <button mat-button type=\"button\" (click)=\"clear(ctrl); picker.close()\">\n {{ 'Clear' | transloco }}\n </button>\n <button mat-raised-button color=\"primary\" matDatepickerApply>{{ 'OK' | transloco }}</button>\n </mat-datepicker-actions>\n </mat-datepicker>\n</ng-container>\n", styles: ["ajf-field .ajf-input-group{width:200px}ajf-field .ajf-input-group .mat-datepicker-toggle{display:inline-flex}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i4$1.MatDatepickerActions, selector: "mat-datepicker-actions, mat-date-range-picker-actions" }, { kind: "directive", type: i4$1.MatDatepickerApply, selector: "[matDatepickerApply], [matDateRangePickerApply]" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.AjfDateValueStringPipe, name: "ajfDateValueString" }, { kind: "pipe", type: i1$1.AjfNodeCompleteNamePipe, name: "ajfNodeCompleteName" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
223
309
  }
224
310
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDateInputFieldComponent, decorators: [{
225
311
  type: Component,
226
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-form-field *ngIf=\"control|async as ctrl\">\n <input\n matInput\n [matDatepicker]=\"picker\"\n [attr.aria-label]=\"instance!|ajfNodeCompleteName\"\n [min]=\"instance!.node.minDate|ajfDateValueString\"\n [max]=\"instance!.node.maxDate|ajfDateValueString\"\n [formControl]=\"ctrl!\"\n readonly\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker>\n <mat-datepicker-actions>\n <button mat-button (click)=\"clear(ctrl); picker.close()\">{{'Clear'|transloco}}</button>\n <button mat-raised-button color=\"primary\" matDatepickerApply>{{'OK'|transloco}}</button>\n </mat-datepicker-actions>\n </mat-datepicker>\n</mat-form-field>\n" }]
227
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
312
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <span class=\"ajf-input-group ajf-control--mono\">\n <input\n [matDatepicker]=\"picker\"\n [attr.aria-label]=\"instance! | ajfNodeCompleteName\"\n [min]=\"instance!.node.minDate | ajfDateValueString\"\n [max]=\"instance!.node.maxDate | ajfDateValueString\"\n [formControl]=\"ctrl!\"\n readonly\n />\n <mat-datepicker-toggle class=\"ajf-input-group-action\" [for]=\"picker\"></mat-datepicker-toggle>\n </span>\n <mat-datepicker #picker>\n <mat-datepicker-actions>\n <button mat-button type=\"button\" (click)=\"clear(ctrl); picker.close()\">\n {{ 'Clear' | transloco }}\n </button>\n <button mat-raised-button color=\"primary\" matDatepickerApply>{{ 'OK' | transloco }}</button>\n </mat-datepicker-actions>\n </mat-datepicker>\n</ng-container>\n", styles: ["ajf-field .ajf-input-group{width:200px}ajf-field .ajf-input-group .mat-datepicker-toggle{display:inline-flex}\n"] }]
313
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
228
314
  type: Inject,
229
315
  args: [AJF_WARNING_ALERT_SERVICE]
230
316
  }] }], propDecorators: { input: [{
@@ -257,13 +343,13 @@ class AjfEmptyFieldComponent extends AjfBaseFieldComponent {
257
343
  constructor(cdr, service, was) {
258
344
  super(cdr, service, was);
259
345
  }
260
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfEmptyFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
261
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfEmptyFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"instance\">\n <h1 [innerHTML]=\"instance.node.label | transloco\"></h1>\n <div [innerHTML]=\"instance.node.HTML | transloco\"></div>\n</ng-container>\n", styles: [""], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
346
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfEmptyFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
347
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfEmptyFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<!-- The field row renders the label; this block carries only the note body. -->\n<div class=\"ajf-note\" *ngIf=\"instance\" [innerHTML]=\"instance.node.HTML | transloco\"></div>\n", styles: ["ajf-field .ajf-note{box-sizing:border-box;width:100%;padding:12px 16px;border-left:3px solid var(--ajf-accent);background:var(--ajf-band);color:var(--ajf-text);font-size:14px;line-height:1.5}ajf-field .ajf-note>:first-child{margin-top:0}ajf-field .ajf-note>:last-child{margin-bottom:0}ajf-field .ajf-note strong,ajf-field .ajf-note b{font-weight:600}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
262
348
  }
263
349
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfEmptyFieldComponent, decorators: [{
264
350
  type: Component,
265
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"instance\">\n <h1 [innerHTML]=\"instance.node.label | transloco\"></h1>\n <div [innerHTML]=\"instance.node.HTML | transloco\"></div>\n</ng-container>\n" }]
266
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
351
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<!-- The field row renders the label; this block carries only the note body. -->\n<div class=\"ajf-note\" *ngIf=\"instance\" [innerHTML]=\"instance.node.HTML | transloco\"></div>\n", styles: ["ajf-field .ajf-note{box-sizing:border-box;width:100%;padding:12px 16px;border-left:3px solid var(--ajf-accent);background:var(--ajf-band);color:var(--ajf-text);font-size:14px;line-height:1.5}ajf-field .ajf-note>:first-child{margin-top:0}ajf-field .ajf-note>:last-child{margin-bottom:0}ajf-field .ajf-note strong,ajf-field .ajf-note b{font-weight:600}\n"] }]
352
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
267
353
  type: Inject,
268
354
  args: [AJF_WARNING_ALERT_SERVICE]
269
355
  }] }] });
@@ -293,13 +379,13 @@ class AjfAudioFieldComponent extends AjfAudioFieldComponent$1 {
293
379
  constructor(cdr, service, was) {
294
380
  super(cdr, service, was);
295
381
  }
296
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfAudioFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
382
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfAudioFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
297
383
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfAudioFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"ajf-field-wrapper\" *ngIf=\"control | async as ctrl\">\n <ajf-audio\n [readonly]=\"!instance?.editable\"\n [formControl]=\"ctrl\"\n ></ajf-audio>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i2$3.AjfAudioComponent, selector: "ajf-audio", inputs: ["readonly"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
298
384
  }
299
385
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfAudioFieldComponent, decorators: [{
300
386
  type: Component,
301
387
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"ajf-field-wrapper\" *ngIf=\"control | async as ctrl\">\n <ajf-audio\n [readonly]=\"!instance?.editable\"\n [formControl]=\"ctrl\"\n ></ajf-audio>\n</div>\n" }]
302
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
388
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
303
389
  type: Inject,
304
390
  args: [AJF_WARNING_ALERT_SERVICE]
305
391
  }] }] });
@@ -329,13 +415,13 @@ class AjfBarcodeFieldComponent extends AjfBaseFieldComponent {
329
415
  constructor(cdr, service, was) {
330
416
  super(cdr, service, was);
331
417
  }
332
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfBarcodeFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
418
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfBarcodeFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
333
419
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfBarcodeFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ajf-barcode *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-barcode>\n", styles: [""], dependencies: [{ kind: "component", type: i2$4.AjfBarcodeComponent, selector: "ajf-barcode" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
334
420
  }
335
421
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfBarcodeFieldComponent, decorators: [{
336
422
  type: Component,
337
423
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ajf-barcode *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-barcode>\n" }]
338
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
424
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
339
425
  type: Inject,
340
426
  args: [AJF_WARNING_ALERT_SERVICE]
341
427
  }] }] });
@@ -371,13 +457,13 @@ class AjfDisplayFieldComponent extends AjfInputFieldComponent$1 {
371
457
  constructor(cdr, service, was) {
372
458
  super(cdr, service, was);
373
459
  }
374
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDisplayFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
375
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfDisplayFieldComponent, selector: "ajf-display-field", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <ng-container [ngSwitch]=\"instance?.node?.fieldType\">\n\n <!-- String -->\n <span *ngSwitchCase=\"0\">{{ ctrl.value }}</span>\n\n <!-- Textarea with HTML -->\n <div *ngSwitchCase=\"1\" [innerHTML]=\"ctrl.value | safeHtml\"></div>\n\n <!-- Number -->\n <span *ngSwitchCase=\"2\">{{ ctrl.value | number }}</span>\n\n <!-- Boolean -->\n <mat-slide-toggle *ngSwitchCase=\"3\" [checked]=\"ctrl.value\" (click)=\"$event.preventDefault()\"\n (change)=\"$event.source.checked = ctrl.value\" [disableRipple]=\"true\">\n </mat-slide-toggle>\n\n <!-- Default -->\n <span *ngSwitchDefault>{{ ctrl.value }}</span>\n\n </ng-container>\n</ng-container>", styles: ["ajf-display-field span{min-height:1em;display:block}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "pipe", type: i4$2.SafeHtmlPipe, name: "safeHtml" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
460
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDisplayFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
461
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfDisplayFieldComponent, selector: "ajf-display-field", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <ng-container [ngSwitch]=\"instance?.node?.fieldType\">\n\n <!-- String -->\n <span *ngSwitchCase=\"0\">{{ ctrl.value }}</span>\n\n <!-- Textarea with HTML -->\n <div *ngSwitchCase=\"1\" [innerHTML]=\"ctrl.value | safeHtml\"></div>\n\n <!-- Number -->\n <span *ngSwitchCase=\"2\">{{ ctrl.value | number }}</span>\n\n <!-- Boolean -->\n <mat-slide-toggle *ngSwitchCase=\"3\" [checked]=\"ctrl.value\" (click)=\"$event.preventDefault()\"\n (change)=\"$event.source.checked = ctrl.value\" [disableRipple]=\"true\">\n </mat-slide-toggle>\n\n <!-- Default -->\n <span *ngSwitchDefault>{{ ctrl.value }}</span>\n\n </ng-container>\n</ng-container>", styles: ["ajf-display-field{display:block;color:var(--ajf-text);font-size:14px;line-height:1.5}ajf-display-field>div>:first-child{margin-top:0}ajf-display-field>div>:last-child{margin-bottom:0}ajf-display-field .mat-mdc-slide-toggle{pointer-events:none}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "pipe", type: i4$2.SafeHtmlPipe, name: "safeHtml" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
376
462
  }
377
463
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfDisplayFieldComponent, decorators: [{
378
464
  type: Component,
379
- args: [{ selector: 'ajf-display-field', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <ng-container [ngSwitch]=\"instance?.node?.fieldType\">\n\n <!-- String -->\n <span *ngSwitchCase=\"0\">{{ ctrl.value }}</span>\n\n <!-- Textarea with HTML -->\n <div *ngSwitchCase=\"1\" [innerHTML]=\"ctrl.value | safeHtml\"></div>\n\n <!-- Number -->\n <span *ngSwitchCase=\"2\">{{ ctrl.value | number }}</span>\n\n <!-- Boolean -->\n <mat-slide-toggle *ngSwitchCase=\"3\" [checked]=\"ctrl.value\" (click)=\"$event.preventDefault()\"\n (change)=\"$event.source.checked = ctrl.value\" [disableRipple]=\"true\">\n </mat-slide-toggle>\n\n <!-- Default -->\n <span *ngSwitchDefault>{{ ctrl.value }}</span>\n\n </ng-container>\n</ng-container>", styles: ["ajf-display-field span{min-height:1em;display:block}\n"] }]
380
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: undefined, decorators: [{
465
+ args: [{ selector: 'ajf-display-field', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <ng-container [ngSwitch]=\"instance?.node?.fieldType\">\n\n <!-- String -->\n <span *ngSwitchCase=\"0\">{{ ctrl.value }}</span>\n\n <!-- Textarea with HTML -->\n <div *ngSwitchCase=\"1\" [innerHTML]=\"ctrl.value | safeHtml\"></div>\n\n <!-- Number -->\n <span *ngSwitchCase=\"2\">{{ ctrl.value | number }}</span>\n\n <!-- Boolean -->\n <mat-slide-toggle *ngSwitchCase=\"3\" [checked]=\"ctrl.value\" (click)=\"$event.preventDefault()\"\n (change)=\"$event.source.checked = ctrl.value\" [disableRipple]=\"true\">\n </mat-slide-toggle>\n\n <!-- Default -->\n <span *ngSwitchDefault>{{ ctrl.value }}</span>\n\n </ng-container>\n</ng-container>", styles: ["ajf-display-field{display:block;color:var(--ajf-text);font-size:14px;line-height:1.5}ajf-display-field>div>:first-child{margin-top:0}ajf-display-field>div>:last-child{margin-bottom:0}ajf-display-field .mat-mdc-slide-toggle{pointer-events:none}\n"] }]
466
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: undefined, decorators: [{
381
467
  type: Inject,
382
468
  args: [AJF_WARNING_ALERT_SERVICE]
383
469
  }] }] });
@@ -407,13 +493,13 @@ class AjfInputFieldComponent extends AjfInputFieldComponent$1 {
407
493
  constructor(cdr, service, was) {
408
494
  super(cdr, service, was);
409
495
  }
410
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfInputFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
411
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfInputFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<mat-form-field *ngIf=\"control|async as ctrl\">\n <input matInput *ngIf=\"type === 'text'\" type=\"text\" [formControl]=\"ctrl!\"\n [readonly]=\"instance!|ajfIsReadonlyInputField\" [attr.aria-labelledby]=\"instance!.node.name\">\n <input matInput *ngIf=\"type === 'number'\" type=\"number\" [formControl]=\"ctrl!\"\n [readonly]=\"instance!|ajfIsReadonlyInputField\" [attr.aria-labelledby]=\"instance!.node.name\">\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.AjfIsReadonlyInputFieldPipe, name: "ajfIsReadonlyInputField" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
496
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfInputFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
497
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfInputFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <input\n *ngIf=\"type === 'text'\"\n class=\"ajf-control\"\n [class.ajf-control--formula]=\"instance!.node.fieldType === 6\"\n [class.ajf-control--mono]=\"instance!.node.fieldType === 6\"\n type=\"text\"\n [formControl]=\"ctrl!\"\n [readonly]=\"instance! | ajfIsReadonlyInputField\"\n [attr.aria-labelledby]=\"instance!.node.name\"\n />\n <input\n *ngIf=\"type === 'number'\"\n class=\"ajf-control ajf-control--mono ajf-control--narrow\"\n type=\"number\"\n [formControl]=\"ctrl!\"\n [readonly]=\"instance! | ajfIsReadonlyInputField\"\n [attr.aria-labelledby]=\"instance!.node.name\"\n />\n</ng-container>\n", styles: ["ajf-field .ajf-control--formula{width:auto;min-width:72px;max-width:240px;border-color:transparent;background:var(--ajf-band);color:var(--ajf-text);text-align:center}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.AjfIsReadonlyInputFieldPipe, name: "ajfIsReadonlyInputField" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
412
498
  }
413
499
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfInputFieldComponent, decorators: [{
414
500
  type: Component,
415
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-form-field *ngIf=\"control|async as ctrl\">\n <input matInput *ngIf=\"type === 'text'\" type=\"text\" [formControl]=\"ctrl!\"\n [readonly]=\"instance!|ajfIsReadonlyInputField\" [attr.aria-labelledby]=\"instance!.node.name\">\n <input matInput *ngIf=\"type === 'number'\" type=\"number\" [formControl]=\"ctrl!\"\n [readonly]=\"instance!|ajfIsReadonlyInputField\" [attr.aria-labelledby]=\"instance!.node.name\">\n</mat-form-field>\n" }]
416
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
501
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <input\n *ngIf=\"type === 'text'\"\n class=\"ajf-control\"\n [class.ajf-control--formula]=\"instance!.node.fieldType === 6\"\n [class.ajf-control--mono]=\"instance!.node.fieldType === 6\"\n type=\"text\"\n [formControl]=\"ctrl!\"\n [readonly]=\"instance! | ajfIsReadonlyInputField\"\n [attr.aria-labelledby]=\"instance!.node.name\"\n />\n <input\n *ngIf=\"type === 'number'\"\n class=\"ajf-control ajf-control--mono ajf-control--narrow\"\n type=\"number\"\n [formControl]=\"ctrl!\"\n [readonly]=\"instance! | ajfIsReadonlyInputField\"\n [attr.aria-labelledby]=\"instance!.node.name\"\n />\n</ng-container>\n", styles: ["ajf-field .ajf-control--formula{width:auto;min-width:72px;max-width:240px;border-color:transparent;background:var(--ajf-band);color:var(--ajf-text);text-align:center}\n"] }]
502
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
417
503
  type: Inject,
418
504
  args: [AJF_WARNING_ALERT_SERVICE]
419
505
  }] }] });
@@ -443,13 +529,13 @@ class AjfGeolocationFieldComponent extends AjfBaseFieldComponent {
443
529
  constructor(cdr, service, was) {
444
530
  super(cdr, service, was);
445
531
  }
446
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfGeolocationFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
532
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfGeolocationFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
447
533
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfGeolocationFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ajf-geolocation *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-geolocation>", styles: [""], dependencies: [{ kind: "component", type: i2$5.AjfGeolocationComponent, selector: "ajf-geolocation" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
448
534
  }
449
535
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfGeolocationFieldComponent, decorators: [{
450
536
  type: Component,
451
537
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ajf-geolocation *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-geolocation>" }]
452
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
538
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
453
539
  type: Inject,
454
540
  args: [AJF_WARNING_ALERT_SERVICE]
455
541
  }] }] });
@@ -477,6 +563,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
477
563
  */
478
564
  const maxChoicesInDom$1 = 40;
479
565
  class AjfMultipleChoiceFieldComponent extends AjfFieldWithChoicesComponent {
566
+ /**
567
+ * Whether the choices collapse into a searchable dropdown. Below the search
568
+ * threshold they are laid out as buttons instead, which reads faster for a
569
+ * short list. `forceExpanded` wins over `forceNarrow`, so a schema can pin
570
+ * either presentation regardless of how many choices there are.
571
+ */
572
+ get isNarrow() {
573
+ const instance = this.instance;
574
+ if (instance == null) {
575
+ return false;
576
+ }
577
+ if (instance.node.forceExpanded) {
578
+ return false;
579
+ }
580
+ return instance.node.forceNarrow || instance.filteredChoices.length > this.expandThreshold;
581
+ }
480
582
  constructor(cdr, service, was, searchThreshold) {
481
583
  super(cdr, service, was, searchThreshold);
482
584
  this.expandThreshold = super.searchThreshold;
@@ -510,6 +612,24 @@ class AjfMultipleChoiceFieldComponent extends AjfFieldWithChoicesComponent {
510
612
  return truncated;
511
613
  }));
512
614
  }
615
+ /** The label shown on a selection chip. */
616
+ labelFor(value) {
617
+ const choice = (this.instance?.filteredChoices || []).find(c => c.value === value);
618
+ if (choice == null) {
619
+ return `${value}`;
620
+ }
621
+ return choice.translatedLabel ?? choice.label;
622
+ }
623
+ /**
624
+ * Drop one value from the selection, from the chip's own button. The click has
625
+ * to be stopped from reaching the trigger, which would reopen the panel.
626
+ */
627
+ removeValue(ctrl, value, event) {
628
+ event.stopPropagation();
629
+ event.preventDefault();
630
+ const current = Array.isArray(ctrl.value) ? ctrl.value : [];
631
+ ctrl.setValue(current.filter(v => v !== value));
632
+ }
513
633
  _onInstanceChange() {
514
634
  this._instanceUpdateForChoicesSub.unsubscribe();
515
635
  this._choicesUpdate$.next();
@@ -524,13 +644,13 @@ class AjfMultipleChoiceFieldComponent extends AjfFieldWithChoicesComponent {
524
644
  this._instanceUpdateForChoicesSub.unsubscribe();
525
645
  this._choicesUpdate$.complete();
526
646
  }
527
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfMultipleChoiceFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }, { token: AJF_SEARCH_ALERT_THRESHOLD, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
528
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AjfMultipleChoiceFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "@if (instance) {\n @if (instance.node.forceNarrow || instance.filteredChoices.length > expandThreshold) {\n <mat-select *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\" [multiple]=\"true\">\n <mat-option [style.backgroundColor]=\"'white'\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search'|transloco\"\n [noEntriesFoundLabel]=\"'Nothing found'|transloco\"\n [enableClearOnEscapePressed]=\"true\">\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <ajf-checkbox-group *ngIf=\"control|async as ctrl\" class=\"ajf-choices-container\"\n [formControl]=\"ctrl!\">\n <ajf-checkbox-group-item [value]=\"choice.value\" *ngFor=\"let choice of instance.filteredChoices\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </ajf-checkbox-group-item>\n </ajf-checkbox-group>\n }\n}\n", styles: [""], dependencies: [{ kind: "component", type: i2$6.CheckboxGroupItem, selector: "ajf-checkbox-group-item" }, { kind: "directive", type: i3$1.AjfCheckboxGroup, selector: "ajf-checkbox-group,[ajf-checkbox-group]", inputs: ["value", "name", "disabled"], outputs: ["change"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i8$1.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
647
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfMultipleChoiceFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }, { token: AJF_SEARCH_ALERT_THRESHOLD, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
648
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AjfMultipleChoiceFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "@if (instance) {\n<ng-container *ngIf=\"control | async as ctrl\">\n <div class=\"ajf-choice-control\">\n @if (isNarrow) {\n <mat-select [formControl]=\"ctrl!\" panelClass=\"ajf-select-panel\" [multiple]=\"true\">\n <mat-select-trigger>\n <span class=\"ajf-chip ajf-chip--removable\" *ngFor=\"let value of ctrl.value\">\n {{ labelFor(value) | transloco }}\n <button\n type=\"button\"\n *ngIf=\"!ctrl.disabled\"\n [attr.aria-label]=\"'Remove' | transloco\"\n (click)=\"removeValue(ctrl!, value, $event)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </span>\n </mat-select-trigger>\n <mat-option class=\"ajf-select-search-option\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search' | transloco\"\n [noEntriesFoundLabel]=\"'Nothing found' | transloco\"\n [enableClearOnEscapePressed]=\"true\"\n >\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <ajf-checkbox-group class=\"ajf-choices-container\" [formControl]=\"ctrl!\">\n <ajf-checkbox-group-item [value]=\"choice.value\" *ngFor=\"let choice of instance.filteredChoices\">\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </ajf-checkbox-group-item>\n </ajf-checkbox-group>\n }\n\n <!-- Dropping the whole selection, next to the per-chip buttons that drop one. -->\n <button\n type=\"button\"\n class=\"ajf-btn--ghost ajf-clear-value\"\n *ngIf=\"hasValue(ctrl) && !ctrl.disabled\"\n (click)=\"clearValue(ctrl, $event)\"\n >\n {{ 'Clear' | transloco }}\n </button>\n </div>\n</ng-container>\n}\n", styles: [""], dependencies: [{ kind: "component", type: i2$6.CheckboxGroupItem, selector: "ajf-checkbox-group-item" }, { kind: "directive", type: i3$1.AjfCheckboxGroup, selector: "ajf-checkbox-group,[ajf-checkbox-group]", inputs: ["value", "name", "disabled"], outputs: ["change"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i6.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i9.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
529
649
  }
530
650
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfMultipleChoiceFieldComponent, decorators: [{
531
651
  type: Component,
532
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (instance) {\n @if (instance.node.forceNarrow || instance.filteredChoices.length > expandThreshold) {\n <mat-select *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\" [multiple]=\"true\">\n <mat-option [style.backgroundColor]=\"'white'\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search'|transloco\"\n [noEntriesFoundLabel]=\"'Nothing found'|transloco\"\n [enableClearOnEscapePressed]=\"true\">\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <ajf-checkbox-group *ngIf=\"control|async as ctrl\" class=\"ajf-choices-container\"\n [formControl]=\"ctrl!\">\n <ajf-checkbox-group-item [value]=\"choice.value\" *ngFor=\"let choice of instance.filteredChoices\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </ajf-checkbox-group-item>\n </ajf-checkbox-group>\n }\n}\n" }]
533
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
652
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (instance) {\n<ng-container *ngIf=\"control | async as ctrl\">\n <div class=\"ajf-choice-control\">\n @if (isNarrow) {\n <mat-select [formControl]=\"ctrl!\" panelClass=\"ajf-select-panel\" [multiple]=\"true\">\n <mat-select-trigger>\n <span class=\"ajf-chip ajf-chip--removable\" *ngFor=\"let value of ctrl.value\">\n {{ labelFor(value) | transloco }}\n <button\n type=\"button\"\n *ngIf=\"!ctrl.disabled\"\n [attr.aria-label]=\"'Remove' | transloco\"\n (click)=\"removeValue(ctrl!, value, $event)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </span>\n </mat-select-trigger>\n <mat-option class=\"ajf-select-search-option\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search' | transloco\"\n [noEntriesFoundLabel]=\"'Nothing found' | transloco\"\n [enableClearOnEscapePressed]=\"true\"\n >\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <ajf-checkbox-group class=\"ajf-choices-container\" [formControl]=\"ctrl!\">\n <ajf-checkbox-group-item [value]=\"choice.value\" *ngFor=\"let choice of instance.filteredChoices\">\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </ajf-checkbox-group-item>\n </ajf-checkbox-group>\n }\n\n <!-- Dropping the whole selection, next to the per-chip buttons that drop one. -->\n <button\n type=\"button\"\n class=\"ajf-btn--ghost ajf-clear-value\"\n *ngIf=\"hasValue(ctrl) && !ctrl.disabled\"\n (click)=\"clearValue(ctrl, $event)\"\n >\n {{ 'Clear' | transloco }}\n </button>\n </div>\n</ng-container>\n}\n" }]
653
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
534
654
  type: Inject,
535
655
  args: [AJF_WARNING_ALERT_SERVICE]
536
656
  }] }, { type: undefined, decorators: [{
@@ -579,13 +699,13 @@ class AjfRangeFieldComponent extends AjfRange {
579
699
  }
580
700
  return nums;
581
701
  }
582
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfRangeFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
583
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfRangeFieldComponent, selector: "ajf-range", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control|async as ctrl\">\n <div\n *ngIf=\"appearance !== 'rating'; else ratingTemplate\"\n [class.ajf-range-no-value]=\"isEmpty(ctrl.value)\"\n >\n <mat-slider\n discrete\n showTickMarks\n [step]=\"step\"\n [min]=\"start\"\n [max]=\"end\"\n [attr.aria-label]=\"name\"\n [attr.name]=\"name\"\n ><input matSliderThumb [value]=\"value\" [formControl]=\"ctrl\" /></mat-slider>\n <div class=\"ajf-range-label\">\n <label>{{isEmpty(ctrl.value) ? ('No value selected'|transloco) : ctrl.value}}</label>\n </div>\n </div>\n \n <ng-template #ratingTemplate>\n <div class=\"ajf-rating-container\">\n <button type=\"button\"\n *ngFor=\"let i of enumerateStars()\"\n class=\"ajf-rating-star\"\n [class.selected]=\"i <= ctrl.value\"\n (click)=\"ctrl.setValue(i)\"\n [attr.aria-label]=\"'Rate ' + i + ' out of ' + end\"\n [attr.name]=\"name\">\n <mat-icon>star</mat-icon>\n </button>\n <div class=\"ajf-range-label\">\n <label>{{ctrl.value}}</label>\n </div>\n </div>\n </ng-template>\n</ng-container>\n", styles: ["ajf-range{display:inline-block;padding-top:20px}ajf-range .ajf-range-label{display:inline-block;padding:0 10px}ajf-range .ajf-range-no-value{--mdc-slider-handle-color: #9e9e9e;--mdc-slider-focus-handle-color: #9e9e9e;--mdc-slider-hover-handle-color: #9e9e9e;--mdc-slider-active-track-color: #9e9e9e;--mdc-slider-inactive-track-color: #9e9e9e;--mdc-slider-with-tick-marks-active-container-color: #fff;--mdc-slider-with-tick-marks-inactive-container-color: #9e9e9e;--mdc-slider-label-container-color: #9e9e9e;--mat-slider-ripple-color: #9e9e9e;--mat-slider-hover-state-layer-color: rgba(158, 158, 158, .05);--mat-slider-focus-state-layer-color: rgba(158, 158, 158, .2)}ajf-range .ajf-range-no-value .ajf-range-label{color:#9e9e9e}ajf-range .ajf-rating-container{display:flex;align-items:center;gap:8px;padding:8px 0}ajf-range .ajf-rating-container .ajf-rating-star{background:none;border:none;cursor:pointer;padding:0;color:#ccc;transition:color .2s}ajf-range .ajf-rating-container .ajf-rating-star.selected{color:gold}ajf-range .ajf-rating-container .ajf-rating-star mat-icon{font-size:32px;height:32px;width:32px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i5$3.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i5$3.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
702
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfRangeFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
703
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfRangeFieldComponent, selector: "ajf-range", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <div\n *ngIf=\"appearance !== 'rating'; else ratingTemplate\"\n class=\"ajf-range\"\n [class.ajf-range-no-value]=\"isEmpty(ctrl.value)\"\n >\n <div class=\"ajf-range-track\">\n <mat-slider\n discrete\n showTickMarks\n [step]=\"step\"\n [min]=\"start\"\n [max]=\"end\"\n [attr.aria-label]=\"name\"\n [attr.name]=\"name\"\n >\n <input matSliderThumb [value]=\"value\" [formControl]=\"ctrl\" />\n </mat-slider>\n <div class=\"ajf-range-bounds\">\n <span>{{ start }}</span>\n <span>{{ end }}</span>\n </div>\n </div>\n <span class=\"ajf-range-value\">{{ isEmpty(ctrl.value) ? '&mdash;' : ctrl.value }}</span>\n </div>\n\n <ng-template #ratingTemplate>\n <div class=\"ajf-rating-container\">\n <button\n type=\"button\"\n *ngFor=\"let i of enumerateStars()\"\n class=\"ajf-rating-star\"\n [class.ajf-selected]=\"i <= ctrl.value\"\n (click)=\"ctrl.setValue(i)\"\n [attr.aria-label]=\"'Rate ' + i + ' out of ' + end\"\n [attr.name]=\"name\"\n >\n <mat-icon>star</mat-icon>\n </button>\n <span class=\"ajf-rating-readout\">{{ ctrl.value || 0 }} / {{ end }}</span>\n </div>\n </ng-template>\n</ng-container>\n", styles: ["ajf-range{display:block;width:100%}ajf-range .ajf-range{display:flex;align-items:center;gap:12px}ajf-range .ajf-range-track{flex:1 1 auto;min-width:180px;max-width:360px}ajf-range .ajf-range-track .mat-mdc-slider{width:100%;margin:0}ajf-range .ajf-range-bounds{display:flex;justify-content:space-between;margin-top:-6px;padding:0 8px;color:var(--ajf-text-muted);font-family:var(--ajf-font-mono);font-size:11px}ajf-range .ajf-range-value{box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;min-width:44px;padding:0 8px;background:var(--ajf-band);font-family:var(--ajf-font-mono);text-align:center}ajf-range .ajf-range-value:focus,ajf-range .ajf-range-value:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}ajf-range .ajf-range-value:disabled,ajf-range .ajf-range-value[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}ajf-range .ajf-range-no-value .mat-mdc-slider{--mdc-slider-active-track-color: var(--ajf-border-strong);--mdc-slider-handle-color: var(--ajf-border-strong);--mdc-slider-focus-handle-color: var(--ajf-border-strong);--mdc-slider-hover-handle-color: var(--ajf-border-strong)}ajf-range .ajf-range-no-value .ajf-range-value{color:var(--ajf-text-faint)}ajf-range .ajf-rating-container{display:flex;align-items:center;gap:4px}ajf-range .ajf-rating-star{padding:0;border:0;background:none;color:var(--ajf-border-strong);cursor:pointer}ajf-range .ajf-rating-star.ajf-selected{color:var(--ajf-accent)}ajf-range .ajf-rating-star .mat-icon{width:26px;height:26px;font-size:26px}ajf-range .ajf-rating-readout{margin-left:8px;color:var(--ajf-text-muted);font-family:var(--ajf-font-mono);font-size:13px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i5$1.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i5$1.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
584
704
  }
585
705
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfRangeFieldComponent, decorators: [{
586
706
  type: Component,
587
- args: [{ selector: 'ajf-range', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control|async as ctrl\">\n <div\n *ngIf=\"appearance !== 'rating'; else ratingTemplate\"\n [class.ajf-range-no-value]=\"isEmpty(ctrl.value)\"\n >\n <mat-slider\n discrete\n showTickMarks\n [step]=\"step\"\n [min]=\"start\"\n [max]=\"end\"\n [attr.aria-label]=\"name\"\n [attr.name]=\"name\"\n ><input matSliderThumb [value]=\"value\" [formControl]=\"ctrl\" /></mat-slider>\n <div class=\"ajf-range-label\">\n <label>{{isEmpty(ctrl.value) ? ('No value selected'|transloco) : ctrl.value}}</label>\n </div>\n </div>\n \n <ng-template #ratingTemplate>\n <div class=\"ajf-rating-container\">\n <button type=\"button\"\n *ngFor=\"let i of enumerateStars()\"\n class=\"ajf-rating-star\"\n [class.selected]=\"i <= ctrl.value\"\n (click)=\"ctrl.setValue(i)\"\n [attr.aria-label]=\"'Rate ' + i + ' out of ' + end\"\n [attr.name]=\"name\">\n <mat-icon>star</mat-icon>\n </button>\n <div class=\"ajf-range-label\">\n <label>{{ctrl.value}}</label>\n </div>\n </div>\n </ng-template>\n</ng-container>\n", styles: ["ajf-range{display:inline-block;padding-top:20px}ajf-range .ajf-range-label{display:inline-block;padding:0 10px}ajf-range .ajf-range-no-value{--mdc-slider-handle-color: #9e9e9e;--mdc-slider-focus-handle-color: #9e9e9e;--mdc-slider-hover-handle-color: #9e9e9e;--mdc-slider-active-track-color: #9e9e9e;--mdc-slider-inactive-track-color: #9e9e9e;--mdc-slider-with-tick-marks-active-container-color: #fff;--mdc-slider-with-tick-marks-inactive-container-color: #9e9e9e;--mdc-slider-label-container-color: #9e9e9e;--mat-slider-ripple-color: #9e9e9e;--mat-slider-hover-state-layer-color: rgba(158, 158, 158, .05);--mat-slider-focus-state-layer-color: rgba(158, 158, 158, .2)}ajf-range .ajf-range-no-value .ajf-range-label{color:#9e9e9e}ajf-range .ajf-rating-container{display:flex;align-items:center;gap:8px;padding:8px 0}ajf-range .ajf-rating-container .ajf-rating-star{background:none;border:none;cursor:pointer;padding:0;color:#ccc;transition:color .2s}ajf-range .ajf-rating-container .ajf-rating-star.selected{color:gold}ajf-range .ajf-rating-container .ajf-rating-star mat-icon{font-size:32px;height:32px;width:32px}\n"] }]
588
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
707
+ args: [{ selector: 'ajf-range', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <div\n *ngIf=\"appearance !== 'rating'; else ratingTemplate\"\n class=\"ajf-range\"\n [class.ajf-range-no-value]=\"isEmpty(ctrl.value)\"\n >\n <div class=\"ajf-range-track\">\n <mat-slider\n discrete\n showTickMarks\n [step]=\"step\"\n [min]=\"start\"\n [max]=\"end\"\n [attr.aria-label]=\"name\"\n [attr.name]=\"name\"\n >\n <input matSliderThumb [value]=\"value\" [formControl]=\"ctrl\" />\n </mat-slider>\n <div class=\"ajf-range-bounds\">\n <span>{{ start }}</span>\n <span>{{ end }}</span>\n </div>\n </div>\n <span class=\"ajf-range-value\">{{ isEmpty(ctrl.value) ? '&mdash;' : ctrl.value }}</span>\n </div>\n\n <ng-template #ratingTemplate>\n <div class=\"ajf-rating-container\">\n <button\n type=\"button\"\n *ngFor=\"let i of enumerateStars()\"\n class=\"ajf-rating-star\"\n [class.ajf-selected]=\"i <= ctrl.value\"\n (click)=\"ctrl.setValue(i)\"\n [attr.aria-label]=\"'Rate ' + i + ' out of ' + end\"\n [attr.name]=\"name\"\n >\n <mat-icon>star</mat-icon>\n </button>\n <span class=\"ajf-rating-readout\">{{ ctrl.value || 0 }} / {{ end }}</span>\n </div>\n </ng-template>\n</ng-container>\n", styles: ["ajf-range{display:block;width:100%}ajf-range .ajf-range{display:flex;align-items:center;gap:12px}ajf-range .ajf-range-track{flex:1 1 auto;min-width:180px;max-width:360px}ajf-range .ajf-range-track .mat-mdc-slider{width:100%;margin:0}ajf-range .ajf-range-bounds{display:flex;justify-content:space-between;margin-top:-6px;padding:0 8px;color:var(--ajf-text-muted);font-family:var(--ajf-font-mono);font-size:11px}ajf-range .ajf-range-value{box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;min-width:44px;padding:0 8px;background:var(--ajf-band);font-family:var(--ajf-font-mono);text-align:center}ajf-range .ajf-range-value:focus,ajf-range .ajf-range-value:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}ajf-range .ajf-range-value:disabled,ajf-range .ajf-range-value[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}ajf-range .ajf-range-no-value .mat-mdc-slider{--mdc-slider-active-track-color: var(--ajf-border-strong);--mdc-slider-handle-color: var(--ajf-border-strong);--mdc-slider-focus-handle-color: var(--ajf-border-strong);--mdc-slider-hover-handle-color: var(--ajf-border-strong)}ajf-range .ajf-range-no-value .ajf-range-value{color:var(--ajf-text-faint)}ajf-range .ajf-rating-container{display:flex;align-items:center;gap:4px}ajf-range .ajf-rating-star{padding:0;border:0;background:none;color:var(--ajf-border-strong);cursor:pointer}ajf-range .ajf-rating-star.ajf-selected{color:var(--ajf-accent)}ajf-range .ajf-rating-star .mat-icon{width:26px;height:26px;font-size:26px}ajf-range .ajf-rating-readout{margin-left:8px;color:var(--ajf-text-muted);font-family:var(--ajf-font-mono);font-size:13px}\n"] }]
708
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
589
709
  type: Inject,
590
710
  args: [AJF_WARNING_ALERT_SERVICE]
591
711
  }] }] });
@@ -613,6 +733,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
613
733
  */
614
734
  const maxChoicesInDom = 40;
615
735
  class AjfSingleChoiceFieldComponent extends AjfFieldWithChoicesComponent {
736
+ /**
737
+ * Whether the choices collapse into a searchable dropdown. Below the search
738
+ * threshold they are laid out as buttons instead, which reads faster for a
739
+ * short list. `forceExpanded` wins over `forceNarrow`, so a schema can pin
740
+ * either presentation regardless of how many choices there are.
741
+ */
742
+ get isNarrow() {
743
+ const instance = this.instance;
744
+ if (instance == null) {
745
+ return false;
746
+ }
747
+ if (instance.node.forceExpanded) {
748
+ return false;
749
+ }
750
+ return instance.node.forceNarrow || instance.filteredChoices.length > this.expandThreshold;
751
+ }
616
752
  constructor(cdr, service, was, searchThreshold) {
617
753
  super(cdr, service, was, searchThreshold);
618
754
  this.expandThreshold = super.searchThreshold;
@@ -658,13 +794,13 @@ class AjfSingleChoiceFieldComponent extends AjfFieldWithChoicesComponent {
658
794
  this._instanceUpdateForChoicesSub.unsubscribe();
659
795
  this._choicesUpdate$.complete();
660
796
  }
661
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSingleChoiceFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }, { token: AJF_SEARCH_ALERT_THRESHOLD, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
662
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AjfSingleChoiceFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "@if (instance) {\n @if (instance.node.forceNarrow || instance.filteredChoices.length > expandThreshold) {\n <mat-select *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\">\n <mat-option [style.backgroundColor]=\"'white'\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search'|transloco\"\n [noEntriesFoundLabel]=\"'Nothing found'|transloco\"\n [enableClearOnEscapePressed]=\"true\">\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <mat-radio-group *ngIf=\"control|async as ctrl\" class=\"ajf-choices-container\"\n [attr.aria-labelledby]=\"instance.node.name\"\n [formControl]=\"ctrl!\">\n <mat-radio-button [value]=\"choice.value\" *ngFor=\"let choice of instance.filteredChoices\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </mat-radio-button>\n </mat-radio-group>\n }\n}\n", styles: [""], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$3.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i3$3.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "component", type: i5$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i8$1.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
797
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSingleChoiceFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }, { token: AJF_SEARCH_ALERT_THRESHOLD, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
798
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AjfSingleChoiceFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "@if (instance) {\n<ng-container *ngIf=\"control | async as ctrl\">\n <div class=\"ajf-choice-control\">\n @if (isNarrow) {\n <mat-select [formControl]=\"ctrl!\" panelClass=\"ajf-select-panel\">\n <mat-option class=\"ajf-select-search-option\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search' | transloco\"\n [noEntriesFoundLabel]=\"'Nothing found' | transloco\"\n [enableClearOnEscapePressed]=\"true\"\n >\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <div\n class=\"ajf-segmented ajf-choices-container\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"instance.node.name\"\n >\n <button\n type=\"button\"\n class=\"ajf-segment\"\n role=\"radio\"\n *ngFor=\"let choice of instance.filteredChoices\"\n [attr.aria-checked]=\"ctrl.value === choice.value\"\n [class.ajf-selected]=\"ctrl.value === choice.value\"\n [disabled]=\"ctrl.disabled\"\n (click)=\"ctrl.setValue(choice.value)\"\n >\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </button>\n </div>\n }\n\n <!-- A picked radio cannot be unpicked, so emptying the field needs its own\n action. -->\n <button\n type=\"button\"\n class=\"ajf-btn--ghost ajf-clear-value\"\n *ngIf=\"hasValue(ctrl) && !ctrl.disabled\"\n (click)=\"clearValue(ctrl, $event)\"\n >\n {{ 'Clear' | transloco }}\n </button>\n </div>\n</ng-container>\n}\n", styles: [".ajf-choice-control{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}.mat-mdc-select-panel.ajf-select-panel{border:1px solid var(--ajf-border, #e6e2dc);background:var(--ajf-surface, #ffffff)}.mat-mdc-select-panel.ajf-select-panel .mat-mdc-option{font-family:var(--ajf-font-sans, sans-serif)}.mat-mdc-select-panel.ajf-select-panel .mat-mdc-option .mdc-list-item__primary-text{color:var(--ajf-text, #1c1a17);font-size:14px}.mat-mdc-select-panel.ajf-select-panel .mat-mdc-option.ajf-select-search-option{min-height:0;padding:0;border-bottom:1px solid var(--ajf-border, #e6e2dc);background:var(--ajf-surface, #ffffff);pointer-events:auto}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i9.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
663
799
  }
664
800
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSingleChoiceFieldComponent, decorators: [{
665
801
  type: Component,
666
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (instance) {\n @if (instance.node.forceNarrow || instance.filteredChoices.length > expandThreshold) {\n <mat-select *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\">\n <mat-option [style.backgroundColor]=\"'white'\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search'|transloco\"\n [noEntriesFoundLabel]=\"'Nothing found'|transloco\"\n [enableClearOnEscapePressed]=\"true\">\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <mat-radio-group *ngIf=\"control|async as ctrl\" class=\"ajf-choices-container\"\n [attr.aria-labelledby]=\"instance.node.name\"\n [formControl]=\"ctrl!\">\n <mat-radio-button [value]=\"choice.value\" *ngFor=\"let choice of instance.filteredChoices\">\n {{ choice.translatedLabel ?? (choice.label|transloco) }}\n </mat-radio-button>\n </mat-radio-group>\n }\n}\n" }]
667
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
802
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (instance) {\n<ng-container *ngIf=\"control | async as ctrl\">\n <div class=\"ajf-choice-control\">\n @if (isNarrow) {\n <mat-select [formControl]=\"ctrl!\" panelClass=\"ajf-select-panel\">\n <mat-option class=\"ajf-select-search-option\">\n <ngx-mat-select-search\n [formControl]=\"searchFilterCtrl\"\n [placeholderLabel]=\"'Search' | transloco\"\n [noEntriesFoundLabel]=\"'Nothing found' | transloco\"\n [enableClearOnEscapePressed]=\"true\"\n >\n </ngx-mat-select-search>\n </mat-option>\n <mat-option [value]=\"choice.value\" *ngFor=\"let choice of filteredChoices$ | async\">\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </mat-option>\n </mat-select>\n } @else {\n <div\n class=\"ajf-segmented ajf-choices-container\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"instance.node.name\"\n >\n <button\n type=\"button\"\n class=\"ajf-segment\"\n role=\"radio\"\n *ngFor=\"let choice of instance.filteredChoices\"\n [attr.aria-checked]=\"ctrl.value === choice.value\"\n [class.ajf-selected]=\"ctrl.value === choice.value\"\n [disabled]=\"ctrl.disabled\"\n (click)=\"ctrl.setValue(choice.value)\"\n >\n {{ choice.translatedLabel ?? (choice.label | transloco) }}\n </button>\n </div>\n }\n\n <!-- A picked radio cannot be unpicked, so emptying the field needs its own\n action. -->\n <button\n type=\"button\"\n class=\"ajf-btn--ghost ajf-clear-value\"\n *ngIf=\"hasValue(ctrl) && !ctrl.disabled\"\n (click)=\"clearValue(ctrl, $event)\"\n >\n {{ 'Clear' | transloco }}\n </button>\n </div>\n</ng-container>\n}\n", styles: [".ajf-choice-control{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}.mat-mdc-select-panel.ajf-select-panel{border:1px solid var(--ajf-border, #e6e2dc);background:var(--ajf-surface, #ffffff)}.mat-mdc-select-panel.ajf-select-panel .mat-mdc-option{font-family:var(--ajf-font-sans, sans-serif)}.mat-mdc-select-panel.ajf-select-panel .mat-mdc-option .mdc-list-item__primary-text{color:var(--ajf-text, #1c1a17);font-size:14px}.mat-mdc-select-panel.ajf-select-panel .mat-mdc-option.ajf-select-search-option{min-height:0;padding:0;border-bottom:1px solid var(--ajf-border, #e6e2dc);background:var(--ajf-surface, #ffffff);pointer-events:auto}\n"] }]
803
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
668
804
  type: Inject,
669
805
  args: [AJF_WARNING_ALERT_SERVICE]
670
806
  }] }, { type: undefined, decorators: [{
@@ -699,13 +835,13 @@ class AjfTableFieldComponent extends AjfTableFieldComponent$1 {
699
835
  constructor(cdr, service, was) {
700
836
  super(cdr, service, was);
701
837
  }
702
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTableFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
703
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfTableFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<table *ngIf=\"instance\" class=\"ajf-table-field\">\n <ng-container *ngIf=\"instance.node as node\">\n <ng-container *ngFor=\"let columns of instance.controls; let row = index\">\n <tr [ngClass]=\"row | ajfTableRowClass\">\n <td>\n <ng-container *ngIf=\"columns.length > 0 && columns[0]\">\n {{ columns[0] | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n </td>\n <ng-container *ngIf=\"columns.length > 1\">\n <td *ngFor=\"let c of columns[1]; let column = index\">\n <ng-container *ngIf=\"row === 0; else controlCell\">\n {{ c | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n <ng-template #controlCell>\n <ng-container *ngIf=\"c|ajfGetTableCellControl as contr\">\n <ng-container *ngIf=\"contr\">\n <ng-container *ngIf=\"contr!.show && (node.rows[row-1][column]|ajfIsCellEditable); else plainTextCell\">\n <ng-container *ngIf=\"contr.type === 'number';else genericInput\">\n <input (focusout)=\"contr!.show = false\" type=\"number\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-container>\n <ng-template #genericInput>\n <input (focusout)=\"contr!.show = false\" [type]=\"contr.type\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-template>\n </ng-container>\n\n <ng-template #plainTextCell>\n <span (click)=\"goToCell(row, column)\">{{ contr.control!.value |\n ajfTranslateIfString | ajfFormatIfNumber: '.0-2'\n }}</span>\n </ng-template>\n </ng-container>\n </ng-container>\n </ng-template>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n</table>", styles: ["table.ajf-table-field{width:100%;border-collapse:collapse;table-layout:fixed}table.ajf-table-field .ajf-header-row{font-weight:700;background-color:#f9f9f9}table.ajf-table-field th,table.ajf-table-field td{padding:12px 15px;text-align:left;border-bottom:1px solid #ddd;border-top:solid 1px transparent;border-right:solid 1px #cccccc;border-left:solid 1px transparent;position:relative}table.ajf-table-field th span,table.ajf-table-field td span{display:inline-block;width:100%;box-sizing:border-box;font-family:inherit;font-size:inherit;line-height:1.5;text-align:center;padding:12px 15px;word-wrap:break-word}table.ajf-table-field th input,table.ajf-table-field td input{cursor:text;position:absolute;width:100%;box-sizing:border-box;outline:none;inset:0;border-top:solid 1px transparent;border-right:solid 1px transparent;border-bottom:solid 1px transparent;border-left:solid 1px transparent;display:inline-block;font-family:inherit;font-size:inherit;line-height:inherit;text-align:center;padding:12px 15px}table.ajf-table-field tr:hover{background-color:#f1f1f1}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i4$2.FormatIfNumber, name: "ajfFormatIfNumber" }, { kind: "pipe", type: i4$2.TranslateIfString, name: "ajfTranslateIfString" }, { kind: "pipe", type: i1.AjfGetTableCellControlPipe, name: "ajfGetTableCellControl" }, { kind: "pipe", type: i1.AjfIsCellEditablePipe, name: "ajfIsCellEditable" }, { kind: "pipe", type: i1.AjfTableRowClass, name: "ajfTableRowClass" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
838
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTableFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
839
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfTableFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<table *ngIf=\"instance\" class=\"ajf-table-field\">\n <ng-container *ngIf=\"instance.node as node\">\n <ng-container *ngFor=\"let columns of instance.controls; let row = index\">\n <tr [ngClass]=\"row | ajfTableRowClass\">\n <td>\n <ng-container *ngIf=\"columns.length > 0 && columns[0]\">\n {{ columns[0] | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n </td>\n <ng-container *ngIf=\"columns.length > 1\">\n <td *ngFor=\"let c of columns[1]; let column = index\">\n <ng-container *ngIf=\"row === 0; else controlCell\">\n {{ c | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n <ng-template #controlCell>\n <ng-container *ngIf=\"c|ajfGetTableCellControl as contr\">\n <ng-container *ngIf=\"contr\">\n <ng-container *ngIf=\"contr!.show && (node.rows[row-1][column]|ajfIsCellEditable); else plainTextCell\">\n <ng-container *ngIf=\"contr.type === 'number';else genericInput\">\n <input (focusout)=\"contr!.show = false\" type=\"number\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-container>\n <ng-template #genericInput>\n <input (focusout)=\"contr!.show = false\" [type]=\"contr.type\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-template>\n </ng-container>\n\n <ng-template #plainTextCell>\n <span (click)=\"goToCell(row, column)\">{{ contr.control!.value |\n ajfTranslateIfString | ajfFormatIfNumber: '.0-2'\n }}</span>\n </ng-template>\n </ng-container>\n </ng-container>\n </ng-template>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n</table>", styles: ["table.ajf-table-field{width:100%;border:1px solid var(--ajf-border);border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:13px}table.ajf-table-field .ajf-header-row{background:var(--ajf-band)}table.ajf-table-field .ajf-header-row td,table.ajf-table-field .ajf-header-row th{color:var(--ajf-text-muted);font-family:var(--ajf-font-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase}table.ajf-table-field th,table.ajf-table-field td{position:relative;padding:9px 12px;border-right:1px solid var(--ajf-border);border-bottom:1px solid var(--ajf-border);text-align:left}table.ajf-table-field th:last-child,table.ajf-table-field td:last-child{border-right:0}table.ajf-table-field tr:last-child td{border-bottom:0}table.ajf-table-field tbody tr:hover:not(.ajf-header-row){background:var(--ajf-band)}table.ajf-table-field td span{display:block;width:100%;min-height:1.4em;box-sizing:border-box;font:inherit;cursor:text;outline:none}table.ajf-table-field td input{position:absolute;inset:0;width:100%;box-sizing:border-box;padding:9px 12px;border:1px solid var(--ajf-accent);background:var(--ajf-surface);color:var(--ajf-text);font:inherit;cursor:text;outline:none}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i4$2.FormatIfNumber, name: "ajfFormatIfNumber" }, { kind: "pipe", type: i4$2.TranslateIfString, name: "ajfTranslateIfString" }, { kind: "pipe", type: i1$1.AjfGetTableCellControlPipe, name: "ajfGetTableCellControl" }, { kind: "pipe", type: i1$1.AjfIsCellEditablePipe, name: "ajfIsCellEditable" }, { kind: "pipe", type: i1$1.AjfTableRowClass, name: "ajfTableRowClass" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
704
840
  }
705
841
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTableFieldComponent, decorators: [{
706
842
  type: Component,
707
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<table *ngIf=\"instance\" class=\"ajf-table-field\">\n <ng-container *ngIf=\"instance.node as node\">\n <ng-container *ngFor=\"let columns of instance.controls; let row = index\">\n <tr [ngClass]=\"row | ajfTableRowClass\">\n <td>\n <ng-container *ngIf=\"columns.length > 0 && columns[0]\">\n {{ columns[0] | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n </td>\n <ng-container *ngIf=\"columns.length > 1\">\n <td *ngFor=\"let c of columns[1]; let column = index\">\n <ng-container *ngIf=\"row === 0; else controlCell\">\n {{ c | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n <ng-template #controlCell>\n <ng-container *ngIf=\"c|ajfGetTableCellControl as contr\">\n <ng-container *ngIf=\"contr\">\n <ng-container *ngIf=\"contr!.show && (node.rows[row-1][column]|ajfIsCellEditable); else plainTextCell\">\n <ng-container *ngIf=\"contr.type === 'number';else genericInput\">\n <input (focusout)=\"contr!.show = false\" type=\"number\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-container>\n <ng-template #genericInput>\n <input (focusout)=\"contr!.show = false\" [type]=\"contr.type\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-template>\n </ng-container>\n\n <ng-template #plainTextCell>\n <span (click)=\"goToCell(row, column)\">{{ contr.control!.value |\n ajfTranslateIfString | ajfFormatIfNumber: '.0-2'\n }}</span>\n </ng-template>\n </ng-container>\n </ng-container>\n </ng-template>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n</table>", styles: ["table.ajf-table-field{width:100%;border-collapse:collapse;table-layout:fixed}table.ajf-table-field .ajf-header-row{font-weight:700;background-color:#f9f9f9}table.ajf-table-field th,table.ajf-table-field td{padding:12px 15px;text-align:left;border-bottom:1px solid #ddd;border-top:solid 1px transparent;border-right:solid 1px #cccccc;border-left:solid 1px transparent;position:relative}table.ajf-table-field th span,table.ajf-table-field td span{display:inline-block;width:100%;box-sizing:border-box;font-family:inherit;font-size:inherit;line-height:1.5;text-align:center;padding:12px 15px;word-wrap:break-word}table.ajf-table-field th input,table.ajf-table-field td input{cursor:text;position:absolute;width:100%;box-sizing:border-box;outline:none;inset:0;border-top:solid 1px transparent;border-right:solid 1px transparent;border-bottom:solid 1px transparent;border-left:solid 1px transparent;display:inline-block;font-family:inherit;font-size:inherit;line-height:inherit;text-align:center;padding:12px 15px}table.ajf-table-field tr:hover{background-color:#f1f1f1}\n"] }]
708
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
843
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<table *ngIf=\"instance\" class=\"ajf-table-field\">\n <ng-container *ngIf=\"instance.node as node\">\n <ng-container *ngFor=\"let columns of instance.controls; let row = index\">\n <tr [ngClass]=\"row | ajfTableRowClass\">\n <td>\n <ng-container *ngIf=\"columns.length > 0 && columns[0]\">\n {{ columns[0] | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n </td>\n <ng-container *ngIf=\"columns.length > 1\">\n <td *ngFor=\"let c of columns[1]; let column = index\">\n <ng-container *ngIf=\"row === 0; else controlCell\">\n {{ c | ajfTranslateIfString | ajfFormatIfNumber: '.0-2' }}\n </ng-container>\n <ng-template #controlCell>\n <ng-container *ngIf=\"c|ajfGetTableCellControl as contr\">\n <ng-container *ngIf=\"contr\">\n <ng-container *ngIf=\"contr!.show && (node.rows[row-1][column]|ajfIsCellEditable); else plainTextCell\">\n <ng-container *ngIf=\"contr.type === 'number';else genericInput\">\n <input (focusout)=\"contr!.show = false\" type=\"number\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-container>\n <ng-template #genericInput>\n <input (focusout)=\"contr!.show = false\" [type]=\"contr.type\" [formControl]=\"contr.control\"\n (keydown.tab)=\"goToNextCell($event, row, column)\" autofocus />\n </ng-template>\n </ng-container>\n\n <ng-template #plainTextCell>\n <span (click)=\"goToCell(row, column)\">{{ contr.control!.value |\n ajfTranslateIfString | ajfFormatIfNumber: '.0-2'\n }}</span>\n </ng-template>\n </ng-container>\n </ng-container>\n </ng-template>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n</table>", styles: ["table.ajf-table-field{width:100%;border:1px solid var(--ajf-border);border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:13px}table.ajf-table-field .ajf-header-row{background:var(--ajf-band)}table.ajf-table-field .ajf-header-row td,table.ajf-table-field .ajf-header-row th{color:var(--ajf-text-muted);font-family:var(--ajf-font-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase}table.ajf-table-field th,table.ajf-table-field td{position:relative;padding:9px 12px;border-right:1px solid var(--ajf-border);border-bottom:1px solid var(--ajf-border);text-align:left}table.ajf-table-field th:last-child,table.ajf-table-field td:last-child{border-right:0}table.ajf-table-field tr:last-child td{border-bottom:0}table.ajf-table-field tbody tr:hover:not(.ajf-header-row){background:var(--ajf-band)}table.ajf-table-field td span{display:block;width:100%;min-height:1.4em;box-sizing:border-box;font:inherit;cursor:text;outline:none}table.ajf-table-field td input{position:absolute;inset:0;width:100%;box-sizing:border-box;padding:9px 12px;border:1px solid var(--ajf-accent);background:var(--ajf-surface);color:var(--ajf-text);font:inherit;cursor:text;outline:none}\n"] }]
844
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
709
845
  type: Inject,
710
846
  args: [AJF_WARNING_ALERT_SERVICE]
711
847
  }] }] });
@@ -755,13 +891,13 @@ class AjfTextFieldComponent extends AjfInputFieldComponent$1 {
755
891
  });
756
892
  }
757
893
  }
758
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTextFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
759
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfTextFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<quill-editor *ngIf=\"control | async as ctrl\" [formControl]=\"ctrl!\" [modules]=\"quillModules\" class=\"resizable-quill\"\n placeholder=\"\">\n</quill-editor>", styles: [".resizable-quill{display:block;width:100%;max-width:800px}.resizable-quill .ql-toolbar{background-color:var(--mdc-filled-text-field-container-color, var(--mat-app-surface-variant))}.resizable-quill .ql-editor{min-height:11.36em;max-height:35.5em;overflow-y:auto;resize:vertical;font-size:var(--mat-form-field-container-text-size, var(--mat-app-body-large-size))}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$3.QuillEditorComponent, selector: "quill-editor" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
894
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTextFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
895
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfTextFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<quill-editor *ngIf=\"control | async as ctrl\" [formControl]=\"ctrl!\" [modules]=\"quillModules\" class=\"resizable-quill\"\n placeholder=\"\">\n</quill-editor>", styles: ["ajf-field .resizable-quill{display:block;width:100%;max-width:720px}ajf-field .resizable-quill .ql-toolbar.ql-snow,ajf-field .resizable-quill .ql-container.ql-snow{border-color:var(--ajf-border-strong)}ajf-field .resizable-quill .ql-toolbar.ql-snow{border-radius:var(--ajf-radius) var(--ajf-radius) 0 0;background:var(--ajf-band)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-stroke{stroke:var(--ajf-text-muted)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-fill{fill:var(--ajf-text-muted)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-active .ql-stroke{stroke:var(--ajf-accent)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-active .ql-fill{fill:var(--ajf-accent)}ajf-field .resizable-quill .ql-container.ql-snow{border-radius:0 0 var(--ajf-radius) var(--ajf-radius);background:var(--ajf-surface);font-family:var(--ajf-font-sans);font-size:14px}ajf-field .resizable-quill .ql-editor{min-height:7.5em;max-height:30em;resize:vertical}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$3.QuillEditorComponent, selector: "quill-editor" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
760
896
  }
761
897
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTextFieldComponent, decorators: [{
762
898
  type: Component,
763
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<quill-editor *ngIf=\"control | async as ctrl\" [formControl]=\"ctrl!\" [modules]=\"quillModules\" class=\"resizable-quill\"\n placeholder=\"\">\n</quill-editor>", styles: [".resizable-quill{display:block;width:100%;max-width:800px}.resizable-quill .ql-toolbar{background-color:var(--mdc-filled-text-field-container-color, var(--mat-app-surface-variant))}.resizable-quill .ql-editor{min-height:11.36em;max-height:35.5em;overflow-y:auto;resize:vertical;font-size:var(--mat-form-field-container-text-size, var(--mat-app-body-large-size))}\n"] }]
764
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
899
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<quill-editor *ngIf=\"control | async as ctrl\" [formControl]=\"ctrl!\" [modules]=\"quillModules\" class=\"resizable-quill\"\n placeholder=\"\">\n</quill-editor>", styles: ["ajf-field .resizable-quill{display:block;width:100%;max-width:720px}ajf-field .resizable-quill .ql-toolbar.ql-snow,ajf-field .resizable-quill .ql-container.ql-snow{border-color:var(--ajf-border-strong)}ajf-field .resizable-quill .ql-toolbar.ql-snow{border-radius:var(--ajf-radius) var(--ajf-radius) 0 0;background:var(--ajf-band)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-stroke{stroke:var(--ajf-text-muted)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-fill{fill:var(--ajf-text-muted)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-active .ql-stroke{stroke:var(--ajf-accent)}ajf-field .resizable-quill .ql-toolbar.ql-snow .ql-active .ql-fill{fill:var(--ajf-accent)}ajf-field .resizable-quill .ql-container.ql-snow{border-radius:0 0 var(--ajf-radius) var(--ajf-radius);background:var(--ajf-surface);font-family:var(--ajf-font-sans);font-size:14px}ajf-field .resizable-quill .ql-editor{min-height:7.5em;max-height:30em;resize:vertical}\n"] }]
900
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
765
901
  type: Inject,
766
902
  args: [AJF_WARNING_ALERT_SERVICE]
767
903
  }] }] });
@@ -791,13 +927,13 @@ class AjfTimeFieldComponent extends AjfBaseFieldComponent {
791
927
  constructor(cdr, service, was) {
792
928
  super(cdr, service, was);
793
929
  }
794
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTimeFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
795
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfTimeFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ajf-time *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-time>\n", styles: [""], dependencies: [{ kind: "component", type: i2$7.AjfTime, selector: "ajf-time" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
930
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTimeFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
931
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfTimeFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ajf-time *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-time>\n", styles: [""], dependencies: [{ kind: "component", type: i2$8.AjfTime, selector: "ajf-time" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
796
932
  }
797
933
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfTimeFieldComponent, decorators: [{
798
934
  type: Component,
799
935
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ajf-time *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-time>\n" }]
800
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
936
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
801
937
  type: Inject,
802
938
  args: [AJF_WARNING_ALERT_SERVICE]
803
939
  }] }] });
@@ -827,16 +963,16 @@ class AjfVideoUrlFieldComponent extends AjfVideoUrlFieldComponent$1 {
827
963
  constructor(cdr, service, was, domSanitizer, httpClient) {
828
964
  super(cdr, service, was, domSanitizer, httpClient);
829
965
  }
830
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfVideoUrlFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }, { token: i2$8.DomSanitizer }, { token: i3$4.HttpClient }], target: i0.ɵɵFactoryTarget.Component }); }
831
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfVideoUrlFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control|async as ctrl\">\n <mat-form-field class=\"ajf-video-input\">\n <input matInput type=\"url\" [formControl]=\"ctrl!\">\n </mat-form-field>\n <div class=\"ajf-video-thumbnail\">\n <ng-container *ngIf=\"validUrl|async\">\n <a target=\"_blank\" [href]=\"ctrl.value\">\n <img *ngIf=\"videoThumbnail|async as thumb\" [src]=\"thumb\" class=\"\" alt=\"\">\n </a>\n </ng-container>\n </div>\n</ng-container>\n", styles: [".ajf-video-input{width:100%}.ajf-video-thumbnail{width:212px;height:120px;background-color:#eee;display:flex;align-items:center;justify-content:center}.ajf-video-thumbnail img{flex:1 1 auto}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
966
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfVideoUrlFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }, { token: i2$9.DomSanitizer }, { token: i3$2.HttpClient }], target: i0.ɵɵFactoryTarget.Component }); }
967
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfVideoUrlFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <input class=\"ajf-control ajf-video-input\" type=\"url\" [formControl]=\"ctrl!\" />\n <div class=\"ajf-video-thumbnail\">\n <ng-container *ngIf=\"validUrl | async\">\n <a target=\"_blank\" [href]=\"ctrl.value\">\n <img *ngIf=\"videoThumbnail | async as thumb\" [src]=\"thumb\" alt=\"\" />\n </a>\n </ng-container>\n </div>\n</ng-container>\n", styles: ["ajf-field .ajf-video-thumbnail img{max-width:160px;max-height:90px;border:1px solid var(--ajf-border);border-radius:var(--ajf-radius)}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
832
968
  }
833
969
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfVideoUrlFieldComponent, decorators: [{
834
970
  type: Component,
835
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control|async as ctrl\">\n <mat-form-field class=\"ajf-video-input\">\n <input matInput type=\"url\" [formControl]=\"ctrl!\">\n </mat-form-field>\n <div class=\"ajf-video-thumbnail\">\n <ng-container *ngIf=\"validUrl|async\">\n <a target=\"_blank\" [href]=\"ctrl.value\">\n <img *ngIf=\"videoThumbnail|async as thumb\" [src]=\"thumb\" class=\"\" alt=\"\">\n </a>\n </ng-container>\n </div>\n</ng-container>\n", styles: [".ajf-video-input{width:100%}.ajf-video-thumbnail{width:212px;height:120px;background-color:#eee;display:flex;align-items:center;justify-content:center}.ajf-video-thumbnail img{flex:1 1 auto}\n"] }]
836
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
971
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"control | async as ctrl\">\n <input class=\"ajf-control ajf-video-input\" type=\"url\" [formControl]=\"ctrl!\" />\n <div class=\"ajf-video-thumbnail\">\n <ng-container *ngIf=\"validUrl | async\">\n <a target=\"_blank\" [href]=\"ctrl.value\">\n <img *ngIf=\"videoThumbnail | async as thumb\" [src]=\"thumb\" alt=\"\" />\n </a>\n </ng-container>\n </div>\n</ng-container>\n", styles: ["ajf-field .ajf-video-thumbnail img{max-width:160px;max-height:90px;border:1px solid var(--ajf-border);border-radius:var(--ajf-radius)}\n"] }]
972
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
837
973
  type: Inject,
838
974
  args: [AJF_WARNING_ALERT_SERVICE]
839
- }] }, { type: i2$8.DomSanitizer }, { type: i3$4.HttpClient }] });
975
+ }] }, { type: i2$9.DomSanitizer }, { type: i3$2.HttpClient }] });
840
976
 
841
977
  /**
842
978
  * @license
@@ -869,13 +1005,13 @@ class AjfSignatureFieldComponent extends AjfBaseFieldComponent {
869
1005
  constructor(cdr, service, was) {
870
1006
  super(cdr, service, was);
871
1007
  }
872
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSignatureFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
873
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfSignatureFieldComponent, selector: "ajf-signature-field", usesInheritance: true, ngImport: i0, template: "<ajf-signature *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-signature>\n", styles: [""], dependencies: [{ kind: "component", type: i2$9.AjfSignatureComponent, selector: "ajf-signature" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1008
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSignatureFieldComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.AjfFormRendererService }, { token: AJF_WARNING_ALERT_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
1009
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfSignatureFieldComponent, selector: "ajf-signature-field", usesInheritance: true, ngImport: i0, template: "<ajf-signature *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-signature>\n", styles: [""], dependencies: [{ kind: "component", type: i2$a.AjfSignatureComponent, selector: "ajf-signature" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
874
1010
  }
875
1011
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSignatureFieldComponent, decorators: [{
876
1012
  type: Component,
877
1013
  args: [{ selector: 'ajf-signature-field', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ajf-signature *ngIf=\"control|async as ctrl\" [formControl]=\"ctrl!\"></ajf-signature>\n" }]
878
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
1014
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.AjfFormRendererService }, { type: AjfWarningAlertService, decorators: [{
879
1015
  type: Inject,
880
1016
  args: [AJF_WARNING_ALERT_SERVICE]
881
1017
  }] }] });
@@ -1030,13 +1166,380 @@ class AjfFormField extends AjfFormField$1 {
1030
1166
  }
1031
1167
  }
1032
1168
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormField, deps: [{ token: i0.ChangeDetectorRef }, { token: AjfFieldService }], target: i0.ɵɵFactoryTarget.Component }); }
1033
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfFormField, selector: "ajf-field,ajf-form-field", usesInheritance: true, ngImport: i0, template: "<div\n *ngIf=\"instance\"\n [ngClass]=\"'ajf-field-' + (instance|ajfNodeCompleteName)\"\n [class.ajf-validated]=\"instance.validationResults|ajfFieldIsValid\"\n (keydown)=\"tabEvent($event, instance)\"\n>\n <ng-template ajf-field-host></ng-template>\n</div>\n<ng-container *ngIf=\"instance && instance.node && instance.node.attachments\">\n <a *ngFor=\"let attachment of instance.node.attachments\"\n [href]=\"attachment.value\" target=\"_blank\">{{attachment.label | transloco}}</a>\n</ng-container>\n<div *ngIf=\"!readonly && instance && instance.validationResults\" class=\"ajf-errors\">\n <ng-container *ngFor=\"let res of instance.validationResults\">\n <div class=\"error\" *ngIf=\"!res.result\">\n {{ res.error|transloco }}\n </div>\n </ng-container>\n</div>\n", styles: ["ajf-field .ajf-choices-container{display:flex;flex-direction:row;flex-wrap:wrap;align-items:stretch}ajf-field .ajf-choices-container ajf-checkbox-group-item{width:100%}ajf-field .ajf-choices-container ajf-checkbox-group-item .mat-mdc-button{display:flex;flex-flow:row wrap;justify-content:flex-start;align-items:center}ajf-field .ajf-item-container{position:relative}ajf-field .ajf-errors{font-style:italic;padding:5px}table{border-collapse:collapse;border-spacing:0}table tr td{position:relative}table tr td span{cursor:text;width:100%;box-sizing:border-box;outline:none;display:inline-block;font-family:inherit;font-size:inherit;line-height:inherit;text-align:center}table tr td input{cursor:text;position:absolute;width:100%;box-sizing:border-box;outline:none;inset:0;display:inline-block;border-top:solid 1px transparent;border-right:solid 1px transparent;border-bottom:solid 1px transparent;border-left:solid 1px transparent;font-family:inherit;font-size:inherit;line-height:inherit;text-align:center}table tr td:last-child span,table tr td:last-child input{border-right-color:#ccc}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.AjfFieldHost, selector: "[ajf-field-host]" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i1.AjfFieldIsValidPipe, name: "ajfFieldIsValid" }, { kind: "pipe", type: i1.AjfNodeCompleteNamePipe, name: "ajfNodeCompleteName" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1169
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfFormField, selector: "ajf-field,ajf-form-field", usesInheritance: true, ngImport: i0, template: "<div\n *ngIf=\"instance\"\n [ngClass]=\"'ajf-field-' + (instance|ajfNodeCompleteName)\"\n [class.ajf-validated]=\"instance.validationResults|ajfFieldIsValid\"\n (keydown)=\"tabEvent($event, instance)\"\n>\n <ng-template ajf-field-host></ng-template>\n</div>\n<ng-container *ngIf=\"instance && instance.node && instance.node.attachments\">\n <a *ngFor=\"let attachment of instance.node.attachments\"\n [href]=\"attachment.value\" target=\"_blank\">{{attachment.label | transloco}}</a>\n</ng-container>\n<div *ngIf=\"!readonly && instance && instance.validationResults\" class=\"ajf-errors\">\n <ng-container *ngFor=\"let res of instance.validationResults\">\n <div class=\"error\" *ngIf=\"!res.result\">\n {{ res.error|transloco }}\n </div>\n </ng-container>\n</div>\n", styles: [":root{--ajf-control-h: 44px;--ajf-slider-min-h: 420px;--ajf-label-col: 280px;--ajf-side-col: 260px;--ajf-gap: 12px;--ajf-radius: 4px;--ajf-font-sans: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--ajf-font-mono: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace;--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #f7f5f2) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #ffffff) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #faf8f5) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #e6e2dc) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #d5cfc6) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #0f4c5c) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #ffffff) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #e8f1f5) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #2d6b7f) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #1c1a17) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #7a736a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #b8362b) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #fdf1ef) );--ajf-text-faint: #a49c92;--ajf-accent-hover: #0c3d4a;--ajf-kbd-bg: rgba(255, 255, 255, .22);--ajf-disabled-bg: #e6e2dc;--ajf-disabled-fg: #5a544c}@media (prefers-color-scheme: dark){:root:not(.ajf-light){--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #212121) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #303030) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #303030) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #424242) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #505050) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #496fca) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #06232b) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #123641) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #9ad4e4) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #f2efe9) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #a9a29a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #ff9b8f) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #3a201c) );--ajf-text-faint: #7a736a;--ajf-accent-hover: #8fcedf;--ajf-kbd-bg: rgba(0, 0, 0, .22);--ajf-disabled-bg: #424242;--ajf-disabled-fg: #c9c3bb}}.ajf-dark{--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #212121) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #303030) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #303030) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #424242) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #505050) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #496fca) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #06232b) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #123641) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #9ad4e4) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #f2efe9) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #a9a29a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #ff9b8f) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #3a201c) );--ajf-text-faint: #7a736a;--ajf-accent-hover: #8fcedf;--ajf-kbd-bg: rgba(0, 0, 0, .22);--ajf-disabled-bg: #424242;--ajf-disabled-fg: #c9c3bb}.ajf-light{--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #f7f5f2) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #ffffff) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #faf8f5) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #e6e2dc) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #d5cfc6) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #0f4c5c) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #ffffff) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #e8f1f5) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #2d6b7f) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #1c1a17) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #7a736a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #b8362b) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #fdf1ef) );--ajf-text-faint: #a49c92;--ajf-accent-hover: #0c3d4a;--ajf-kbd-bg: rgba(255, 255, 255, .22);--ajf-disabled-bg: #e6e2dc;--ajf-disabled-fg: #5a544c}.ajf-form-container,ajf-field{color-scheme:light dark}.ajf-dark .ajf-form-container,.ajf-dark ajf-field{color-scheme:dark}.ajf-light .ajf-form-container,.ajf-light ajf-field{color-scheme:light}.ajf-control{box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 12px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;width:100%;max-width:360px}.ajf-control:focus,.ajf-control:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}.ajf-control:disabled,.ajf-control[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}.ajf-control--mono{font-family:var(--ajf-font-mono);font-size:13px;letter-spacing:.01em}.ajf-control--narrow{max-width:160px}.ajf-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 16px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer}.ajf-btn:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-btn:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-btn--primary{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 16px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer;border-color:var(--ajf-accent);background:var(--ajf-accent);color:var(--ajf-accent-fg)}.ajf-btn--primary:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-btn--primary:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-btn--primary:hover:not(:disabled){border-color:var(--ajf-accent-hover);background:var(--ajf-accent-hover)}.ajf-btn--primary:disabled{border-color:var(--ajf-disabled-bg);background:var(--ajf-disabled-bg);color:var(--ajf-disabled-fg)}.ajf-btn--ghost{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer;min-height:auto;padding:0 4px;border-color:transparent;background:none;color:var(--ajf-accent-ink);text-decoration:none}.ajf-btn--ghost:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-btn--ghost:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-btn--ghost:hover:not(:disabled){border-color:transparent;text-decoration:underline}.ajf-btn--ghost.ajf-danger{color:var(--ajf-danger)}.ajf-segmented{display:inline-flex;flex-wrap:wrap;gap:8px}.ajf-segmented .ajf-segment{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 16px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer}.ajf-segmented .ajf-segment:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-segmented .ajf-segment:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-segmented .ajf-segment.ajf-selected{border-color:var(--ajf-accent);background:var(--ajf-accent);color:var(--ajf-accent-fg)}.ajf-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:var(--ajf-radius);background:var(--ajf-accent-soft);color:var(--ajf-accent-ink);font-size:13px;white-space:nowrap}.ajf-chip--removable button{display:inline-flex;align-items:center;padding:0;border:0;background:none;color:inherit;cursor:pointer;opacity:.7}.ajf-chip--removable button:hover{opacity:1}.ajf-chip--removable button .mat-icon{width:14px;height:14px;font-size:14px}.ajf-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;background:var(--ajf-band);color:var(--ajf-text-muted);font-size:12px;white-space:nowrap}.ajf-pill--danger{background:var(--ajf-danger-bg);color:var(--ajf-danger);font-weight:500}.ajf-kbd{padding:1px 5px;border-radius:3px;background:var(--ajf-kbd-bg);font-family:var(--ajf-font-mono);font-size:10px}.ajf-input-group{display:inline-flex;align-items:center;overflow:hidden;box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;padding:0}.ajf-input-group:focus,.ajf-input-group:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}.ajf-input-group:disabled,.ajf-input-group[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}.ajf-input-group>input{flex:1 1 auto;min-width:0;height:calc(var(--ajf-control-h) - 2px);padding:0 12px;border:0;background:none;color:inherit;font:inherit;outline:none}.ajf-input-group>.ajf-input-group-action{display:inline-flex;align-items:center;justify-content:center;align-self:stretch;padding:0 8px;border:0;border-left:1px solid var(--ajf-border);background:var(--ajf-band);color:var(--ajf-text-muted);cursor:pointer}.ajf-hatch{background-color:var(--ajf-band);background-image:repeating-linear-gradient(45deg,var(--ajf-border) 0,var(--ajf-border) 1px,transparent 1px,transparent 7px)}.ajf-micro-label{font-family:var(--ajf-font-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--ajf-text-muted)}ajf-field .mat-mdc-select{box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 12px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;display:inline-flex;align-items:center;width:auto;min-width:240px;max-width:100%}ajf-field .mat-mdc-select:focus,ajf-field .mat-mdc-select:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}ajf-field .mat-mdc-select:disabled,ajf-field .mat-mdc-select[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}ajf-field .mat-mdc-select .mat-mdc-select-trigger{height:auto}ajf-field .mat-mdc-select .mat-mdc-select-value{color:var(--ajf-text);font-size:14px}ajf-field .mat-mdc-select .mat-mdc-select-arrow-wrapper{color:var(--ajf-text-muted)}ajf-field .mat-mdc-select-multiple{min-height:var(--ajf-control-h)}ajf-field .mat-mdc-select-multiple .mat-mdc-select-value{display:flex;flex-wrap:wrap;padding:5px 0}ajf-field .mat-mdc-select-multiple mat-select-trigger{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-width:0}ajf-field .mat-mdc-slide-toggle{--mdc-switch-selected-track-color: var(--ajf-accent);--mdc-switch-selected-handle-color: var(--ajf-surface);--mdc-switch-selected-hover-track-color: var(--ajf-accent);--mdc-switch-selected-focus-track-color: var(--ajf-accent);--mdc-switch-selected-pressed-track-color: var(--ajf-accent);--mdc-switch-selected-hover-handle-color: var(--ajf-surface);--mdc-switch-selected-focus-handle-color: var(--ajf-surface);--mdc-switch-selected-pressed-handle-color: var(--ajf-surface)}ajf-field .mat-mdc-slider{--mdc-slider-handle-color: var(--ajf-accent);--mdc-slider-focus-handle-color: var(--ajf-accent);--mdc-slider-hover-handle-color: var(--ajf-accent);--mdc-slider-active-track-color: var(--ajf-accent);--mdc-slider-inactive-track-color: var(--ajf-border);--mdc-slider-with-tick-marks-active-container-color: var(--ajf-accent-fg);--mdc-slider-with-tick-marks-inactive-container-color: var(--ajf-border-strong);--mdc-slider-handle-elevation: none;--mat-slider-ripple-color: var(--ajf-accent)}ajf-field .mat-datepicker-toggle .mat-mdc-icon-button{width:34px;height:34px;padding:5px;color:var(--ajf-text-muted)}ajf-field{display:block;min-width:0;font-family:var(--ajf-font-sans)}ajf-field .ajf-choices-container{display:flex;flex-direction:row;flex-wrap:wrap;align-items:stretch;gap:8px}ajf-field .ajf-item-container{position:relative}ajf-field .ajf-errors{color:var(--ajf-danger);font-size:13px}ajf-field>a{color:var(--ajf-accent-ink);font-size:13px}ajf-field-row ajf-field .ajf-errors{display:none}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{appearance:none;margin:0}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.AjfFieldHost, selector: "[ajf-field-host]" }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i1$1.AjfFieldIsValidPipe, name: "ajfFieldIsValid" }, { kind: "pipe", type: i1$1.AjfNodeCompleteNamePipe, name: "ajfNodeCompleteName" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1034
1170
  }
1035
1171
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormField, decorators: [{
1036
1172
  type: Component,
1037
- args: [{ selector: 'ajf-field,ajf-form-field', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n *ngIf=\"instance\"\n [ngClass]=\"'ajf-field-' + (instance|ajfNodeCompleteName)\"\n [class.ajf-validated]=\"instance.validationResults|ajfFieldIsValid\"\n (keydown)=\"tabEvent($event, instance)\"\n>\n <ng-template ajf-field-host></ng-template>\n</div>\n<ng-container *ngIf=\"instance && instance.node && instance.node.attachments\">\n <a *ngFor=\"let attachment of instance.node.attachments\"\n [href]=\"attachment.value\" target=\"_blank\">{{attachment.label | transloco}}</a>\n</ng-container>\n<div *ngIf=\"!readonly && instance && instance.validationResults\" class=\"ajf-errors\">\n <ng-container *ngFor=\"let res of instance.validationResults\">\n <div class=\"error\" *ngIf=\"!res.result\">\n {{ res.error|transloco }}\n </div>\n </ng-container>\n</div>\n", styles: ["ajf-field .ajf-choices-container{display:flex;flex-direction:row;flex-wrap:wrap;align-items:stretch}ajf-field .ajf-choices-container ajf-checkbox-group-item{width:100%}ajf-field .ajf-choices-container ajf-checkbox-group-item .mat-mdc-button{display:flex;flex-flow:row wrap;justify-content:flex-start;align-items:center}ajf-field .ajf-item-container{position:relative}ajf-field .ajf-errors{font-style:italic;padding:5px}table{border-collapse:collapse;border-spacing:0}table tr td{position:relative}table tr td span{cursor:text;width:100%;box-sizing:border-box;outline:none;display:inline-block;font-family:inherit;font-size:inherit;line-height:inherit;text-align:center}table tr td input{cursor:text;position:absolute;width:100%;box-sizing:border-box;outline:none;inset:0;display:inline-block;border-top:solid 1px transparent;border-right:solid 1px transparent;border-bottom:solid 1px transparent;border-left:solid 1px transparent;font-family:inherit;font-size:inherit;line-height:inherit;text-align:center}table tr td:last-child span,table tr td:last-child input{border-right-color:#ccc}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] }]
1173
+ args: [{ selector: 'ajf-field,ajf-form-field', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n *ngIf=\"instance\"\n [ngClass]=\"'ajf-field-' + (instance|ajfNodeCompleteName)\"\n [class.ajf-validated]=\"instance.validationResults|ajfFieldIsValid\"\n (keydown)=\"tabEvent($event, instance)\"\n>\n <ng-template ajf-field-host></ng-template>\n</div>\n<ng-container *ngIf=\"instance && instance.node && instance.node.attachments\">\n <a *ngFor=\"let attachment of instance.node.attachments\"\n [href]=\"attachment.value\" target=\"_blank\">{{attachment.label | transloco}}</a>\n</ng-container>\n<div *ngIf=\"!readonly && instance && instance.validationResults\" class=\"ajf-errors\">\n <ng-container *ngFor=\"let res of instance.validationResults\">\n <div class=\"error\" *ngIf=\"!res.result\">\n {{ res.error|transloco }}\n </div>\n </ng-container>\n</div>\n", styles: [":root{--ajf-control-h: 44px;--ajf-slider-min-h: 420px;--ajf-label-col: 280px;--ajf-side-col: 260px;--ajf-gap: 12px;--ajf-radius: 4px;--ajf-font-sans: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--ajf-font-mono: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace;--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #f7f5f2) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #ffffff) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #faf8f5) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #e6e2dc) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #d5cfc6) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #0f4c5c) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #ffffff) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #e8f1f5) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #2d6b7f) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #1c1a17) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #7a736a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #b8362b) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #fdf1ef) );--ajf-text-faint: #a49c92;--ajf-accent-hover: #0c3d4a;--ajf-kbd-bg: rgba(255, 255, 255, .22);--ajf-disabled-bg: #e6e2dc;--ajf-disabled-fg: #5a544c}@media (prefers-color-scheme: dark){:root:not(.ajf-light){--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #212121) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #303030) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #303030) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #424242) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #505050) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #496fca) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #06232b) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #123641) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #9ad4e4) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #f2efe9) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #a9a29a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #ff9b8f) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #3a201c) );--ajf-text-faint: #7a736a;--ajf-accent-hover: #8fcedf;--ajf-kbd-bg: rgba(0, 0, 0, .22);--ajf-disabled-bg: #424242;--ajf-disabled-fg: #c9c3bb}}.ajf-dark{--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #212121) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #303030) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #303030) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #424242) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #505050) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #496fca) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #06232b) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #123641) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #9ad4e4) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #f2efe9) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #a9a29a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #ff9b8f) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #3a201c) );--ajf-text-faint: #7a736a;--ajf-accent-hover: #8fcedf;--ajf-kbd-bg: rgba(0, 0, 0, .22);--ajf-disabled-bg: #424242;--ajf-disabled-fg: #c9c3bb}.ajf-light{--ajf-bg: var( --mat-sys-surface-container-low, var(--sys-surface-container-low, #f7f5f2) );--ajf-surface: var( --mat-sys-surface, var(--sys-surface, #ffffff) );--ajf-band: var( --mat-sys-surface-container, var(--sys-surface-container, #faf8f5) );--ajf-border: var( --mat-sys-outline-variant, var(--sys-outline-variant, #e6e2dc) );--ajf-border-strong: var( --mat-sys-outline, var(--sys-outline, #d5cfc6) );--ajf-accent: var( --mat-sys-primary, var(--sys-primary, #0f4c5c) );--ajf-accent-fg: var( --mat-sys-on-primary, var(--sys-on-primary, #ffffff) );--ajf-accent-soft: var( --mat-sys-primary-container, var(--sys-primary-container, #e8f1f5) );--ajf-accent-ink: var( --mat-sys-on-primary-container, var(--sys-on-primary-container, #2d6b7f) );--ajf-text: var( --mat-sys-on-surface, var(--sys-on-surface, #1c1a17) );--ajf-text-muted: var( --mat-sys-on-surface-variant, var(--sys-on-surface-variant, #7a736a) );--ajf-danger: var( --mat-sys-error, var(--sys-error, #b8362b) );--ajf-danger-bg: var( --mat-sys-error-container, var(--sys-error-container, #fdf1ef) );--ajf-text-faint: #a49c92;--ajf-accent-hover: #0c3d4a;--ajf-kbd-bg: rgba(255, 255, 255, .22);--ajf-disabled-bg: #e6e2dc;--ajf-disabled-fg: #5a544c}.ajf-form-container,ajf-field{color-scheme:light dark}.ajf-dark .ajf-form-container,.ajf-dark ajf-field{color-scheme:dark}.ajf-light .ajf-form-container,.ajf-light ajf-field{color-scheme:light}.ajf-control{box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 12px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;width:100%;max-width:360px}.ajf-control:focus,.ajf-control:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}.ajf-control:disabled,.ajf-control[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}.ajf-control--mono{font-family:var(--ajf-font-mono);font-size:13px;letter-spacing:.01em}.ajf-control--narrow{max-width:160px}.ajf-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 16px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer}.ajf-btn:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-btn:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-btn--primary{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 16px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer;border-color:var(--ajf-accent);background:var(--ajf-accent);color:var(--ajf-accent-fg)}.ajf-btn--primary:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-btn--primary:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-btn--primary:hover:not(:disabled){border-color:var(--ajf-accent-hover);background:var(--ajf-accent-hover)}.ajf-btn--primary:disabled{border-color:var(--ajf-disabled-bg);background:var(--ajf-disabled-bg);color:var(--ajf-disabled-fg)}.ajf-btn--ghost{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer;min-height:auto;padding:0 4px;border-color:transparent;background:none;color:var(--ajf-accent-ink);text-decoration:none}.ajf-btn--ghost:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-btn--ghost:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-btn--ghost:hover:not(:disabled){border-color:transparent;text-decoration:underline}.ajf-btn--ghost.ajf-danger{color:var(--ajf-danger)}.ajf-segmented{display:inline-flex;flex-wrap:wrap;gap:8px}.ajf-segmented .ajf-segment{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 16px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer}.ajf-segmented .ajf-segment:hover:not(:disabled){border-color:var(--ajf-accent)}.ajf-segmented .ajf-segment:disabled{color:var(--ajf-text-faint);cursor:default}.ajf-segmented .ajf-segment.ajf-selected{border-color:var(--ajf-accent);background:var(--ajf-accent);color:var(--ajf-accent-fg)}.ajf-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:var(--ajf-radius);background:var(--ajf-accent-soft);color:var(--ajf-accent-ink);font-size:13px;white-space:nowrap}.ajf-chip--removable button{display:inline-flex;align-items:center;padding:0;border:0;background:none;color:inherit;cursor:pointer;opacity:.7}.ajf-chip--removable button:hover{opacity:1}.ajf-chip--removable button .mat-icon{width:14px;height:14px;font-size:14px}.ajf-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;background:var(--ajf-band);color:var(--ajf-text-muted);font-size:12px;white-space:nowrap}.ajf-pill--danger{background:var(--ajf-danger-bg);color:var(--ajf-danger);font-weight:500}.ajf-kbd{padding:1px 5px;border-radius:3px;background:var(--ajf-kbd-bg);font-family:var(--ajf-font-mono);font-size:10px}.ajf-input-group{display:inline-flex;align-items:center;overflow:hidden;box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;padding:0}.ajf-input-group:focus,.ajf-input-group:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}.ajf-input-group:disabled,.ajf-input-group[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}.ajf-input-group>input{flex:1 1 auto;min-width:0;height:calc(var(--ajf-control-h) - 2px);padding:0 12px;border:0;background:none;color:inherit;font:inherit;outline:none}.ajf-input-group>.ajf-input-group-action{display:inline-flex;align-items:center;justify-content:center;align-self:stretch;padding:0 8px;border:0;border-left:1px solid var(--ajf-border);background:var(--ajf-band);color:var(--ajf-text-muted);cursor:pointer}.ajf-hatch{background-color:var(--ajf-band);background-image:repeating-linear-gradient(45deg,var(--ajf-border) 0,var(--ajf-border) 1px,transparent 1px,transparent 7px)}.ajf-micro-label{font-family:var(--ajf-font-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--ajf-text-muted)}ajf-field .mat-mdc-select{box-sizing:border-box;min-height:var(--ajf-control-h);padding:0 12px;border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;line-height:calc(var(--ajf-control-h) - 2px);outline:none;display:inline-flex;align-items:center;width:auto;min-width:240px;max-width:100%}ajf-field .mat-mdc-select:focus,ajf-field .mat-mdc-select:focus-within{border-color:var(--ajf-accent);box-shadow:0 0 0 2px var(--ajf-accent-soft)}ajf-field .mat-mdc-select:disabled,ajf-field .mat-mdc-select[readonly]{color:var(--ajf-text-muted);background:var(--ajf-band)}ajf-field .mat-mdc-select .mat-mdc-select-trigger{height:auto}ajf-field .mat-mdc-select .mat-mdc-select-value{color:var(--ajf-text);font-size:14px}ajf-field .mat-mdc-select .mat-mdc-select-arrow-wrapper{color:var(--ajf-text-muted)}ajf-field .mat-mdc-select-multiple{min-height:var(--ajf-control-h)}ajf-field .mat-mdc-select-multiple .mat-mdc-select-value{display:flex;flex-wrap:wrap;padding:5px 0}ajf-field .mat-mdc-select-multiple mat-select-trigger{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-width:0}ajf-field .mat-mdc-slide-toggle{--mdc-switch-selected-track-color: var(--ajf-accent);--mdc-switch-selected-handle-color: var(--ajf-surface);--mdc-switch-selected-hover-track-color: var(--ajf-accent);--mdc-switch-selected-focus-track-color: var(--ajf-accent);--mdc-switch-selected-pressed-track-color: var(--ajf-accent);--mdc-switch-selected-hover-handle-color: var(--ajf-surface);--mdc-switch-selected-focus-handle-color: var(--ajf-surface);--mdc-switch-selected-pressed-handle-color: var(--ajf-surface)}ajf-field .mat-mdc-slider{--mdc-slider-handle-color: var(--ajf-accent);--mdc-slider-focus-handle-color: var(--ajf-accent);--mdc-slider-hover-handle-color: var(--ajf-accent);--mdc-slider-active-track-color: var(--ajf-accent);--mdc-slider-inactive-track-color: var(--ajf-border);--mdc-slider-with-tick-marks-active-container-color: var(--ajf-accent-fg);--mdc-slider-with-tick-marks-inactive-container-color: var(--ajf-border-strong);--mdc-slider-handle-elevation: none;--mat-slider-ripple-color: var(--ajf-accent)}ajf-field .mat-datepicker-toggle .mat-mdc-icon-button{width:34px;height:34px;padding:5px;color:var(--ajf-text-muted)}ajf-field{display:block;min-width:0;font-family:var(--ajf-font-sans)}ajf-field .ajf-choices-container{display:flex;flex-direction:row;flex-wrap:wrap;align-items:stretch;gap:8px}ajf-field .ajf-item-container{position:relative}ajf-field .ajf-errors{color:var(--ajf-danger);font-size:13px}ajf-field>a{color:var(--ajf-accent-ink);font-size:13px}ajf-field-row ajf-field .ajf-errors{display:none}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{appearance:none;margin:0}\n"] }]
1038
1174
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: AjfFieldService }] });
1039
1175
 
1176
+ /**
1177
+ * @license
1178
+ * Copyright (C) Gnucoop soc. coop.
1179
+ *
1180
+ * This file is part of the Advanced JSON forms (ajf).
1181
+ *
1182
+ * Advanced JSON forms (ajf) is free software: you can redistribute it and/or
1183
+ * modify it under the terms of the GNU Affero General Public License as
1184
+ * published by the Free Software Foundation, either version 3 of the License,
1185
+ * or (at your option) any later version.
1186
+ *
1187
+ * Advanced JSON forms (ajf) is distributed in the hope that it will be useful,
1188
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1189
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
1190
+ * General Public License for more details.
1191
+ *
1192
+ * You should have received a copy of the GNU Affero General Public License
1193
+ * along with Advanced JSON forms (ajf).
1194
+ * If not, see http://www.gnu.org/licenses/.
1195
+ *
1196
+ */
1197
+ /**
1198
+ * One field of a slide, laid out as a row: type badge, label, control, and a
1199
+ * right-hand column carrying either the field description or its validation
1200
+ * error.
1201
+ *
1202
+ * Both the plain and the repeating slide branches of the renderer render through
1203
+ * this component, so the row layout is defined in exactly one place.
1204
+ */
1205
+ class AjfFieldRow {
1206
+ set instance(instance) {
1207
+ this._instance = instance;
1208
+ // Validity, visibility and the error list are mutated in place on the
1209
+ // instance, so the row has to be told to re-check itself the same way the
1210
+ // field components do.
1211
+ this._instanceSub.unsubscribe();
1212
+ this._instanceSub = instance
1213
+ ? instance.updatedEvt.subscribe(() => this._cdr.markForCheck())
1214
+ : Subscription.EMPTY;
1215
+ }
1216
+ get instance() {
1217
+ return this._instance;
1218
+ }
1219
+ constructor(_cdr) {
1220
+ this._cdr = _cdr;
1221
+ this._instanceSub = Subscription.EMPTY;
1222
+ this._readonly = false;
1223
+ }
1224
+ ngOnDestroy() {
1225
+ this._instanceSub.unsubscribe();
1226
+ }
1227
+ set readonly(readonly) {
1228
+ this._readonly = coerceBooleanProperty(readonly);
1229
+ }
1230
+ get readonly() {
1231
+ return this._readonly;
1232
+ }
1233
+ /**
1234
+ * Rows drop out on the host element rather than inside it, so that a hidden
1235
+ * field leaves no empty cell behind when rows are laid out in columns.
1236
+ *
1237
+ * Three kinds of node carry no information of their own and are kept out of
1238
+ * the layout: a container node, which is only a bracket around the fields it
1239
+ * holds and has no fieldType to render; a formula field with no label, which
1240
+ * only feeds other fields; and a note with no body -- the renderer synthesises
1241
+ * one of those to carry a node group's label, and a group is meant to show
1242
+ * nothing of itself.
1243
+ */
1244
+ get hidden() {
1245
+ const node = this.instance?.node;
1246
+ // Truthy, not `=== false`: a visibility condition is an arbitrary expression
1247
+ // and the renderer stores whatever it returns, so an unanswered field can
1248
+ // leave `visible` at null rather than at false.
1249
+ if (node == null || !this.instance.visible) {
1250
+ return true;
1251
+ }
1252
+ if (node.nodeType !== AjfNodeType.AjfField) {
1253
+ return true;
1254
+ }
1255
+ if (node.fieldType === AjfFieldType.Empty) {
1256
+ return !node.HTML;
1257
+ }
1258
+ return node.fieldType === AjfFieldType.Formula && node.label === '';
1259
+ }
1260
+ /** Notes render their own block and never get a control border around it. */
1261
+ get isNote() {
1262
+ return this.instance?.node.fieldType === AjfFieldType.Empty;
1263
+ }
1264
+ get required() {
1265
+ return this.instance?.node.validation?.notEmpty != null;
1266
+ }
1267
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFieldRow, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1268
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfFieldRow, selector: "ajf-field-row", inputs: { instance: "instance", readonly: "readonly" }, host: { properties: { "class.ajf-hidden-row": "this.hidden" } }, ngImport: i0, template: "<div\n *ngIf=\"!hidden\"\n class=\"ajf-field-row\"\n [class.ajf-invalid]=\"!instance.valid\"\n [class.ajf-readonly]=\"readonly\"\n [class.ajf-note-row]=\"isNote\"\n [ngClass]=\"'ajf-' + instance.node.size + ' ajf-field-type-' + instance.node.fieldType\"\n>\n <div class=\"ajf-field-label\">\n <span class=\"ajf-field-label-line\">\n <label [attr.id]=\"instance.node.name\" [innerHTML]=\"instance.node.label | transloco\"></label>\n <span class=\"ajf-required\" *ngIf=\"required\" aria-hidden=\"true\">*</span>\n <mat-icon\n class=\"ajf-hint-icon\"\n *ngIf=\"instance.node.hint as hint\"\n [matTooltip]=\"hint | transloco\"\n matTooltipPosition=\"right\"\n >{{ instance.node.hintIcon || 'help' }}</mat-icon\n >\n </span>\n <!-- A note carries prose, not a value, so naming its type says nothing. -->\n <ng-container *ngIf=\"!isNote\">\n <span class=\"ajf-field-type-name\" *ngIf=\"instance | ajfFieldTypeLabel as type\"\n >{{ type.name | transloco }}<ng-container *ngIf=\"type.detailValue\"> &middot;\n {{ type.detailValue }}<ng-container *ngIf=\"type.detailUnit\">\n {{ type.detailUnit | transloco }}</ng-container\n ></ng-container\n ></span\n >\n </ng-container>\n </div>\n\n <div class=\"ajf-field-control\">\n <ajf-field\n [instance]=\"instance\"\n [readonly]=\"readonly\"\n [id]=\"'field_entry_' + instance.node.id\"\n ></ajf-field>\n </div>\n\n <div class=\"ajf-field-side\">\n <span class=\"ajf-field-error-message\" *ngIf=\"!instance.valid\">{{\n instance | ajfAsFieldInstanceErrors | transloco\n }}</span>\n <span class=\"ajf-field-hint-text\" *ngIf=\"instance.valid && instance.node.description\">{{\n instance.node.description | transloco\n }}</span>\n </div>\n</div>\n", styles: ["ajf-field-row{display:block}ajf-field-row.ajf-hidden-row{display:none}ajf-field-row .ajf-field-row{display:flex;flex-wrap:nowrap;align-items:flex-start;gap:var(--ajf-gap);box-sizing:border-box;padding:10px 20px;border-bottom:1px solid var(--ajf-border);background:var(--ajf-surface);font-family:var(--ajf-font-sans)}ajf-field-row .ajf-field-label{display:flex;flex:0 0 var(--ajf-label-col);flex-direction:column;justify-content:center;gap:2px;min-height:var(--ajf-control-h);max-width:var(--ajf-label-col)}ajf-field-row .ajf-field-label .ajf-field-label-line{display:flex;align-items:center;gap:6px}ajf-field-row .ajf-field-label label{color:var(--ajf-text);font-size:14px;font-weight:500;line-height:1.35}ajf-field-row .ajf-field-label .ajf-field-type-name{color:var(--ajf-text-muted);font-size:12px;line-height:1.3}ajf-field-row .ajf-field-label .ajf-required{color:var(--ajf-danger);font-weight:600}ajf-field-row .ajf-field-label .ajf-hint-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--ajf-text-muted);font-size:16px;line-height:1;cursor:help}ajf-field-row .ajf-field-control{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}ajf-field-row .ajf-field-control>ajf-field{flex:1 1 auto;min-width:0}ajf-field-row .ajf-field-side{display:flex;flex:0 0 var(--ajf-side-col);align-items:center;min-height:var(--ajf-control-h);max-width:var(--ajf-side-col)}ajf-field-row .ajf-field-side .ajf-field-hint-text{color:var(--ajf-text-muted);font-size:13px}ajf-field-row .ajf-field-side .ajf-field-error-message{color:var(--ajf-danger);font-size:13px}ajf-field-row .ajf-normal .ajf-field-control{max-width:none}ajf-field-row .ajf-small .ajf-field-control{max-width:420px}ajf-field-row .ajf-smaller .ajf-field-control{max-width:320px}ajf-field-row .ajf-tiny .ajf-field-control{max-width:220px}ajf-field-row .ajf-mini .ajf-field-control{max-width:140px}ajf-field-row .ajf-field-row.ajf-invalid{background:color-mix(in srgb,var(--ajf-danger-bg) 45%,var(--ajf-surface))}ajf-field-row .ajf-field-row.ajf-invalid .ajf-control,ajf-field-row .ajf-field-row.ajf-invalid input.ajf-control,ajf-field-row .ajf-field-row.ajf-invalid .mat-mdc-select-trigger{border-color:var(--ajf-danger)}ajf-field-row .ajf-field-row.ajf-readonly .ajf-field-side{flex-basis:auto}ajf-field-row .ajf-note-row .ajf-field-control,ajf-field-row .ajf-field-type-1 .ajf-field-control,ajf-field-row .ajf-field-type-11 .ajf-field-control{max-width:none}@media (width <= 900px){ajf-field-row .ajf-field-row{flex-wrap:wrap;padding:12px 16px}ajf-field-row .ajf-field-label,ajf-field-row .ajf-field-side{flex-basis:100%;max-width:none;min-height:0}ajf-field-row .ajf-field-control{flex-basis:100%}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3$3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: AjfFormField, selector: "ajf-field,ajf-form-field" }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i1$1.AjfAsFieldInstanceErrorsPipe, name: "ajfAsFieldInstanceErrors" }, { kind: "pipe", type: i1$1.AjfFieldTypeLabelPipe, name: "ajfFieldTypeLabel" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1269
+ }
1270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFieldRow, decorators: [{
1271
+ type: Component,
1272
+ args: [{ selector: 'ajf-field-row', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n *ngIf=\"!hidden\"\n class=\"ajf-field-row\"\n [class.ajf-invalid]=\"!instance.valid\"\n [class.ajf-readonly]=\"readonly\"\n [class.ajf-note-row]=\"isNote\"\n [ngClass]=\"'ajf-' + instance.node.size + ' ajf-field-type-' + instance.node.fieldType\"\n>\n <div class=\"ajf-field-label\">\n <span class=\"ajf-field-label-line\">\n <label [attr.id]=\"instance.node.name\" [innerHTML]=\"instance.node.label | transloco\"></label>\n <span class=\"ajf-required\" *ngIf=\"required\" aria-hidden=\"true\">*</span>\n <mat-icon\n class=\"ajf-hint-icon\"\n *ngIf=\"instance.node.hint as hint\"\n [matTooltip]=\"hint | transloco\"\n matTooltipPosition=\"right\"\n >{{ instance.node.hintIcon || 'help' }}</mat-icon\n >\n </span>\n <!-- A note carries prose, not a value, so naming its type says nothing. -->\n <ng-container *ngIf=\"!isNote\">\n <span class=\"ajf-field-type-name\" *ngIf=\"instance | ajfFieldTypeLabel as type\"\n >{{ type.name | transloco }}<ng-container *ngIf=\"type.detailValue\"> &middot;\n {{ type.detailValue }}<ng-container *ngIf=\"type.detailUnit\">\n {{ type.detailUnit | transloco }}</ng-container\n ></ng-container\n ></span\n >\n </ng-container>\n </div>\n\n <div class=\"ajf-field-control\">\n <ajf-field\n [instance]=\"instance\"\n [readonly]=\"readonly\"\n [id]=\"'field_entry_' + instance.node.id\"\n ></ajf-field>\n </div>\n\n <div class=\"ajf-field-side\">\n <span class=\"ajf-field-error-message\" *ngIf=\"!instance.valid\">{{\n instance | ajfAsFieldInstanceErrors | transloco\n }}</span>\n <span class=\"ajf-field-hint-text\" *ngIf=\"instance.valid && instance.node.description\">{{\n instance.node.description | transloco\n }}</span>\n </div>\n</div>\n", styles: ["ajf-field-row{display:block}ajf-field-row.ajf-hidden-row{display:none}ajf-field-row .ajf-field-row{display:flex;flex-wrap:nowrap;align-items:flex-start;gap:var(--ajf-gap);box-sizing:border-box;padding:10px 20px;border-bottom:1px solid var(--ajf-border);background:var(--ajf-surface);font-family:var(--ajf-font-sans)}ajf-field-row .ajf-field-label{display:flex;flex:0 0 var(--ajf-label-col);flex-direction:column;justify-content:center;gap:2px;min-height:var(--ajf-control-h);max-width:var(--ajf-label-col)}ajf-field-row .ajf-field-label .ajf-field-label-line{display:flex;align-items:center;gap:6px}ajf-field-row .ajf-field-label label{color:var(--ajf-text);font-size:14px;font-weight:500;line-height:1.35}ajf-field-row .ajf-field-label .ajf-field-type-name{color:var(--ajf-text-muted);font-size:12px;line-height:1.3}ajf-field-row .ajf-field-label .ajf-required{color:var(--ajf-danger);font-weight:600}ajf-field-row .ajf-field-label .ajf-hint-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--ajf-text-muted);font-size:16px;line-height:1;cursor:help}ajf-field-row .ajf-field-control{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}ajf-field-row .ajf-field-control>ajf-field{flex:1 1 auto;min-width:0}ajf-field-row .ajf-field-side{display:flex;flex:0 0 var(--ajf-side-col);align-items:center;min-height:var(--ajf-control-h);max-width:var(--ajf-side-col)}ajf-field-row .ajf-field-side .ajf-field-hint-text{color:var(--ajf-text-muted);font-size:13px}ajf-field-row .ajf-field-side .ajf-field-error-message{color:var(--ajf-danger);font-size:13px}ajf-field-row .ajf-normal .ajf-field-control{max-width:none}ajf-field-row .ajf-small .ajf-field-control{max-width:420px}ajf-field-row .ajf-smaller .ajf-field-control{max-width:320px}ajf-field-row .ajf-tiny .ajf-field-control{max-width:220px}ajf-field-row .ajf-mini .ajf-field-control{max-width:140px}ajf-field-row .ajf-field-row.ajf-invalid{background:color-mix(in srgb,var(--ajf-danger-bg) 45%,var(--ajf-surface))}ajf-field-row .ajf-field-row.ajf-invalid .ajf-control,ajf-field-row .ajf-field-row.ajf-invalid input.ajf-control,ajf-field-row .ajf-field-row.ajf-invalid .mat-mdc-select-trigger{border-color:var(--ajf-danger)}ajf-field-row .ajf-field-row.ajf-readonly .ajf-field-side{flex-basis:auto}ajf-field-row .ajf-note-row .ajf-field-control,ajf-field-row .ajf-field-type-1 .ajf-field-control,ajf-field-row .ajf-field-type-11 .ajf-field-control{max-width:none}@media (width <= 900px){ajf-field-row .ajf-field-row{flex-wrap:wrap;padding:12px 16px}ajf-field-row .ajf-field-label,ajf-field-row .ajf-field-side{flex-basis:100%;max-width:none;min-height:0}ajf-field-row .ajf-field-control{flex-basis:100%}}\n"] }]
1273
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { instance: [{
1274
+ type: Input
1275
+ }], readonly: [{
1276
+ type: Input
1277
+ }], hidden: [{
1278
+ type: HostBinding,
1279
+ args: ['class.ajf-hidden-row']
1280
+ }] } });
1281
+
1282
+ /**
1283
+ * The pager for a repeating slide: one button per repetition plus add and remove
1284
+ * actions. The renderer keeps one page per repetition, so picking a number here
1285
+ * is a page change, which the renderer performs.
1286
+ */
1287
+ class AjfRepStrip {
1288
+ constructor() {
1289
+ /** The repetition currently on screen, zero based. */
1290
+ this.current = 0;
1291
+ this._readonly = false;
1292
+ this.goTo = new EventEmitter();
1293
+ this.add = new EventEmitter();
1294
+ this.remove = new EventEmitter();
1295
+ }
1296
+ set readonly(readonly) {
1297
+ this._readonly = coerceBooleanProperty(readonly);
1298
+ }
1299
+ get readonly() {
1300
+ return this._readonly;
1301
+ }
1302
+ /**
1303
+ * A repetition count driven by a formula is not the reader's to change:
1304
+ * `AjfFormRendererService.addGroup` and `removeGroup` both refuse the call
1305
+ * outright, so without this the buttons would sit enabled and do nothing.
1306
+ */
1307
+ get manualReps() {
1308
+ return this.slide.formulaReps == null;
1309
+ }
1310
+ get canAdd() {
1311
+ return this.manualReps && !!this.slide.canAdd;
1312
+ }
1313
+ get canRemove() {
1314
+ return this.manualReps && !!this.slide.canRemove;
1315
+ }
1316
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfRepStrip, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1317
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfRepStrip, selector: "ajf-rep-strip", inputs: { slide: "slide", current: "current", readonly: "readonly" }, outputs: { goTo: "goTo", add: "add", remove: "remove" }, ngImport: i0, template: "<div class=\"ajf-rep-strip\">\n <span class=\"ajf-micro-label ajf-rep-strip-label\"\n >{{ 'Number of' | transloco }} {{ slide.node.label | transloco }}</span\n >\n\n <div class=\"ajf-rep-pager\">\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"current === 0\"\n (click)=\"goTo.emit(current - 1)\"\n [attr.aria-label]=\"'Back' | transloco\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn ajf-rep-page\"\n *ngFor=\"let rep of (slide.reps | ajfRange); let idx = index\"\n [class.ajf-selected]=\"idx === current\"\n (click)=\"goTo.emit(idx)\"\n >\n {{ idx + 1 }}\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"current >= slide.reps - 1\"\n (click)=\"goTo.emit(current + 1)\"\n [attr.aria-label]=\"'Forward' | transloco\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n\n <ng-container *ngIf=\"!readonly\">\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"!canAdd\"\n (click)=\"add.emit()\"\n [attr.aria-label]=\"'Add' | transloco\"\n >\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"!canRemove\"\n (click)=\"remove.emit()\"\n [attr.aria-label]=\"'Remove' | transloco\"\n >\n <mat-icon>remove</mat-icon>\n </button>\n </ng-container>\n </div>\n\n <span class=\"ajf-rep-strip-context\">\n <span [innerHTML]=\"slide.node.label | transloco\"></span>\n {{ current + 1 }} {{ 'of' | transloco }} {{ slide.reps }}\n </span>\n</div>\n", styles: ["ajf-rep-strip{display:block}ajf-rep-strip .ajf-rep-strip{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 20px;border-bottom:1px solid var(--ajf-border);background:var(--ajf-band);font-family:var(--ajf-font-sans)}ajf-rep-strip .ajf-rep-strip-label{flex:0 0 auto}ajf-rep-strip .ajf-rep-pager{display:flex;flex-wrap:wrap;gap:6px}ajf-rep-strip .ajf-rep-pager .ajf-btn{min-width:32px;min-height:32px;padding:0 6px;font-size:13px}ajf-rep-strip .ajf-rep-pager .ajf-btn .mat-icon{width:18px;height:18px;font-size:18px}ajf-rep-strip .ajf-rep-pager .ajf-rep-page.ajf-selected{border-color:var(--ajf-accent);background:var(--ajf-accent);color:var(--ajf-accent-fg)}ajf-rep-strip .ajf-rep-strip-context{margin-left:auto;color:var(--ajf-text-muted);font-size:13px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i1$1.AjfRangePipe, name: "ajfRange" }], encapsulation: i0.ViewEncapsulation.None }); }
1318
+ }
1319
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfRepStrip, decorators: [{
1320
+ type: Component,
1321
+ args: [{ selector: 'ajf-rep-strip', encapsulation: ViewEncapsulation.None, template: "<div class=\"ajf-rep-strip\">\n <span class=\"ajf-micro-label ajf-rep-strip-label\"\n >{{ 'Number of' | transloco }} {{ slide.node.label | transloco }}</span\n >\n\n <div class=\"ajf-rep-pager\">\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"current === 0\"\n (click)=\"goTo.emit(current - 1)\"\n [attr.aria-label]=\"'Back' | transloco\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn ajf-rep-page\"\n *ngFor=\"let rep of (slide.reps | ajfRange); let idx = index\"\n [class.ajf-selected]=\"idx === current\"\n (click)=\"goTo.emit(idx)\"\n >\n {{ idx + 1 }}\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"current >= slide.reps - 1\"\n (click)=\"goTo.emit(current + 1)\"\n [attr.aria-label]=\"'Forward' | transloco\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n\n <ng-container *ngIf=\"!readonly\">\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"!canAdd\"\n (click)=\"add.emit()\"\n [attr.aria-label]=\"'Add' | transloco\"\n >\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn\"\n [disabled]=\"!canRemove\"\n (click)=\"remove.emit()\"\n [attr.aria-label]=\"'Remove' | transloco\"\n >\n <mat-icon>remove</mat-icon>\n </button>\n </ng-container>\n </div>\n\n <span class=\"ajf-rep-strip-context\">\n <span [innerHTML]=\"slide.node.label | transloco\"></span>\n {{ current + 1 }} {{ 'of' | transloco }} {{ slide.reps }}\n </span>\n</div>\n", styles: ["ajf-rep-strip{display:block}ajf-rep-strip .ajf-rep-strip{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 20px;border-bottom:1px solid var(--ajf-border);background:var(--ajf-band);font-family:var(--ajf-font-sans)}ajf-rep-strip .ajf-rep-strip-label{flex:0 0 auto}ajf-rep-strip .ajf-rep-pager{display:flex;flex-wrap:wrap;gap:6px}ajf-rep-strip .ajf-rep-pager .ajf-btn{min-width:32px;min-height:32px;padding:0 6px;font-size:13px}ajf-rep-strip .ajf-rep-pager .ajf-btn .mat-icon{width:18px;height:18px;font-size:18px}ajf-rep-strip .ajf-rep-pager .ajf-rep-page.ajf-selected{border-color:var(--ajf-accent);background:var(--ajf-accent);color:var(--ajf-accent-fg)}ajf-rep-strip .ajf-rep-strip-context{margin-left:auto;color:var(--ajf-text-muted);font-size:13px}\n"] }]
1322
+ }], propDecorators: { slide: [{
1323
+ type: Input
1324
+ }], current: [{
1325
+ type: Input
1326
+ }], readonly: [{
1327
+ type: Input
1328
+ }], goTo: [{
1329
+ type: Output
1330
+ }], add: [{
1331
+ type: Output
1332
+ }], remove: [{
1333
+ type: Output
1334
+ }] } });
1335
+
1336
+ /**
1337
+ * The bar at the top of every slide: its number and title, a menu to jump to any
1338
+ * other slide, previous/next paging, and a slot for the form's own action
1339
+ * buttons.
1340
+ *
1341
+ * What the form still has failing is reported by the footer alone. Naming it
1342
+ * here too cost a phone's whole header width to repeat something already on
1343
+ * screen.
1344
+ *
1345
+ * Paging belongs to the renderer, which owns the page slider, so it is raised
1346
+ * as an event rather than handled here.
1347
+ */
1348
+ class AjfSlideHeader {
1349
+ constructor() {
1350
+ /** Absent while a start or end message page is on screen. */
1351
+ this.slide = null;
1352
+ /** The number shown in the badge, already offset by any start message. */
1353
+ this.displayNumber = 1;
1354
+ /** Every slide of the form, for the jump menu. */
1355
+ this.slides = [];
1356
+ /** How many pages the slider holds, repetitions and message pages included. */
1357
+ this.pages = 0;
1358
+ this.jumpTo = new EventEmitter();
1359
+ this.prev = new EventEmitter();
1360
+ this.next = new EventEmitter();
1361
+ }
1362
+ /**
1363
+ * Whether the form has anywhere to page to. A single page form gets no arrows
1364
+ * and no "slide 1 of 1": both are controls that cannot do anything.
1365
+ */
1366
+ get canNavigate() {
1367
+ return this.pages > 1;
1368
+ }
1369
+ /**
1370
+ * Whether the jump menu is worth opening. Counted over the visible slides, the
1371
+ * only ones the menu can actually reach.
1372
+ */
1373
+ get canJump() {
1374
+ return this.slides.filter(s => s.visible !== false).length > 1;
1375
+ }
1376
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideHeader, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1377
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfSlideHeader, selector: "ajf-slide-header", inputs: { slide: "slide", displayNumber: "displayNumber", slides: "slides", pages: "pages" }, outputs: { jumpTo: "jumpTo", prev: "prev", next: "next" }, ngImport: i0, template: "<div class=\"ajf-slide-header\">\n <button\n type=\"button\"\n class=\"ajf-slide-title\"\n [class.ajf-slide-title-static]=\"!slide || !canJump\"\n [disabled]=\"!slide || !canJump\"\n [matMenuTriggerFor]=\"slideMenu\"\n [attr.aria-label]=\"'Go to slide' | transloco\"\n >\n <span class=\"ajf-slide-number\">{{ displayNumber }}</span>\n\n <!-- Every slide title is laid out in the same grid cell, so the trigger is as\n wide as the longest of them and keeps that width while paging. Only the\n current title is visible; the rest just hold the space open. -->\n <span class=\"ajf-slide-label-stack\">\n <span\n class=\"ajf-slide-label\"\n *ngFor=\"let s of slides\"\n [class.ajf-current]=\"s === slide\"\n [innerHTML]=\"s.node.label | transloco\"\n ></span>\n </span>\n <mat-icon class=\"ajf-slide-caret\" *ngIf=\"slide && canJump\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #slideMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let s of slides\"\n [disabled]=\"s.visible === false\"\n (click)=\"jumpTo.emit(s)\"\n >\n <mat-icon [class.ajf-invalid]=\"!s.valid\">{{ s.valid ? 'check' : 'warning' }}</mat-icon>\n <span [innerHTML]=\"s.node.label | transloco\"></span>\n </button>\n </mat-menu>\n\n <!-- Nothing to page through in a single page form. -->\n <div class=\"ajf-slide-nav\" *ngIf=\"canNavigate\">\n <button\n type=\"button\"\n class=\"ajf-btn\"\n (click)=\"prev.emit()\"\n [attr.aria-label]=\"'Back' | transloco\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn\"\n (click)=\"next.emit()\"\n [attr.aria-label]=\"'Forward' | transloco\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n\n <span class=\"ajf-slide-header-spacer\"></span>\n\n <ng-content></ng-content>\n</div>\n", styles: ["ajf-slide-header{display:block}ajf-slide-header .ajf-slide-header{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 20px;background:var(--ajf-surface);font-family:var(--ajf-font-sans)}ajf-slide-header .ajf-slide-header-spacer{flex:1 1 auto}ajf-slide-header .ajf-slide-title{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer;flex:0 1 auto;justify-content:flex-start;gap:10px;max-width:100%;padding:0 12px}ajf-slide-header .ajf-slide-title:hover:not(:disabled){border-color:var(--ajf-accent)}ajf-slide-header .ajf-slide-title:disabled{color:var(--ajf-text-faint);cursor:default}ajf-slide-header .ajf-slide-title .ajf-slide-number{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--ajf-accent);color:var(--ajf-accent-fg);font-size:12px;font-weight:600}ajf-slide-header .ajf-slide-title .ajf-slide-label-stack{display:grid;min-width:0;max-width:340px;text-align:left}ajf-slide-header .ajf-slide-title .ajf-slide-label{grid-area:1/1;overflow:hidden;visibility:hidden;font-size:16px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}ajf-slide-header .ajf-slide-title .ajf-slide-label.ajf-current{visibility:visible}ajf-slide-header .ajf-slide-title .ajf-slide-caret{width:20px;height:20px;margin-left:auto;color:var(--ajf-text-muted);font-size:20px}ajf-slide-header .ajf-slide-title-static{cursor:default}ajf-slide-header .ajf-slide-title-static:hover{border-color:var(--ajf-border-strong)}ajf-slide-header .ajf-slide-nav{display:flex;gap:8px}ajf-slide-header .ajf-slide-nav .ajf-btn{width:var(--ajf-control-h);padding:0}.mat-mdc-menu-panel .mat-mdc-menu-item .mat-icon.ajf-invalid{color:var(--ajf-danger)}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i3$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }], encapsulation: i0.ViewEncapsulation.None }); }
1378
+ }
1379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideHeader, decorators: [{
1380
+ type: Component,
1381
+ args: [{ selector: 'ajf-slide-header', encapsulation: ViewEncapsulation.None, template: "<div class=\"ajf-slide-header\">\n <button\n type=\"button\"\n class=\"ajf-slide-title\"\n [class.ajf-slide-title-static]=\"!slide || !canJump\"\n [disabled]=\"!slide || !canJump\"\n [matMenuTriggerFor]=\"slideMenu\"\n [attr.aria-label]=\"'Go to slide' | transloco\"\n >\n <span class=\"ajf-slide-number\">{{ displayNumber }}</span>\n\n <!-- Every slide title is laid out in the same grid cell, so the trigger is as\n wide as the longest of them and keeps that width while paging. Only the\n current title is visible; the rest just hold the space open. -->\n <span class=\"ajf-slide-label-stack\">\n <span\n class=\"ajf-slide-label\"\n *ngFor=\"let s of slides\"\n [class.ajf-current]=\"s === slide\"\n [innerHTML]=\"s.node.label | transloco\"\n ></span>\n </span>\n <mat-icon class=\"ajf-slide-caret\" *ngIf=\"slide && canJump\">arrow_drop_down</mat-icon>\n </button>\n\n <mat-menu #slideMenu=\"matMenu\">\n <button\n mat-menu-item\n *ngFor=\"let s of slides\"\n [disabled]=\"s.visible === false\"\n (click)=\"jumpTo.emit(s)\"\n >\n <mat-icon [class.ajf-invalid]=\"!s.valid\">{{ s.valid ? 'check' : 'warning' }}</mat-icon>\n <span [innerHTML]=\"s.node.label | transloco\"></span>\n </button>\n </mat-menu>\n\n <!-- Nothing to page through in a single page form. -->\n <div class=\"ajf-slide-nav\" *ngIf=\"canNavigate\">\n <button\n type=\"button\"\n class=\"ajf-btn\"\n (click)=\"prev.emit()\"\n [attr.aria-label]=\"'Back' | transloco\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"ajf-btn\"\n (click)=\"next.emit()\"\n [attr.aria-label]=\"'Forward' | transloco\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n\n <span class=\"ajf-slide-header-spacer\"></span>\n\n <ng-content></ng-content>\n</div>\n", styles: ["ajf-slide-header{display:block}ajf-slide-header .ajf-slide-header{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 20px;background:var(--ajf-surface);font-family:var(--ajf-font-sans)}ajf-slide-header .ajf-slide-header-spacer{flex:1 1 auto}ajf-slide-header .ajf-slide-title{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;min-height:var(--ajf-control-h);border:1px solid var(--ajf-border-strong);border-radius:var(--ajf-radius);background:var(--ajf-surface);color:var(--ajf-text);font-family:var(--ajf-font-sans);font-size:14px;cursor:pointer;flex:0 1 auto;justify-content:flex-start;gap:10px;max-width:100%;padding:0 12px}ajf-slide-header .ajf-slide-title:hover:not(:disabled){border-color:var(--ajf-accent)}ajf-slide-header .ajf-slide-title:disabled{color:var(--ajf-text-faint);cursor:default}ajf-slide-header .ajf-slide-title .ajf-slide-number{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--ajf-accent);color:var(--ajf-accent-fg);font-size:12px;font-weight:600}ajf-slide-header .ajf-slide-title .ajf-slide-label-stack{display:grid;min-width:0;max-width:340px;text-align:left}ajf-slide-header .ajf-slide-title .ajf-slide-label{grid-area:1/1;overflow:hidden;visibility:hidden;font-size:16px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}ajf-slide-header .ajf-slide-title .ajf-slide-label.ajf-current{visibility:visible}ajf-slide-header .ajf-slide-title .ajf-slide-caret{width:20px;height:20px;margin-left:auto;color:var(--ajf-text-muted);font-size:20px}ajf-slide-header .ajf-slide-title-static{cursor:default}ajf-slide-header .ajf-slide-title-static:hover{border-color:var(--ajf-border-strong)}ajf-slide-header .ajf-slide-nav{display:flex;gap:8px}ajf-slide-header .ajf-slide-nav .ajf-btn{width:var(--ajf-control-h);padding:0}.mat-mdc-menu-panel .mat-mdc-menu-item .mat-icon.ajf-invalid{color:var(--ajf-danger)}\n"] }]
1382
+ }], propDecorators: { slide: [{
1383
+ type: Input
1384
+ }], displayNumber: [{
1385
+ type: Input
1386
+ }], slides: [{
1387
+ type: Input
1388
+ }], pages: [{
1389
+ type: Input
1390
+ }], jumpTo: [{
1391
+ type: Output
1392
+ }], prev: [{
1393
+ type: Output
1394
+ }], next: [{
1395
+ type: Output
1396
+ }] } });
1397
+
1398
+ /**
1399
+ * @license
1400
+ * Copyright (C) Gnucoop soc. coop.
1401
+ *
1402
+ * This file is part of the Advanced JSON forms (ajf).
1403
+ *
1404
+ * Advanced JSON forms (ajf) is free software: you can redistribute it and/or
1405
+ * modify it under the terms of the GNU Affero General Public License as
1406
+ * published by the Free Software Foundation, either version 3 of the License,
1407
+ * or (at your option) any later version.
1408
+ *
1409
+ * Advanced JSON forms (ajf) is distributed in the hope that it will be useful,
1410
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1411
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
1412
+ * General Public License for more details.
1413
+ *
1414
+ * You should have received a copy of the GNU Affero General Public License
1415
+ * along with Advanced JSON forms (ajf).
1416
+ * If not, see http://www.gnu.org/licenses/.
1417
+ *
1418
+ */
1419
+ /**
1420
+ * The fields a slide header counts. `slideNodes` is indexed per repetition, and
1421
+ * a non-repeating slide keeps its only set of nodes at index 0, so both kinds of
1422
+ * slide are read the same way.
1423
+ */
1424
+ const countableFields = (slide, idx) => {
1425
+ const nodes = (slide.slideNodes && slide.slideNodes[idx]) || slide.flatNodes || [];
1426
+ return nodes.filter(n => n.visible && isFieldInstance(n) && n.node.fieldType !== AjfFieldType.Empty);
1427
+ };
1428
+ /**
1429
+ * Whether a field holds anything.
1430
+ *
1431
+ * The value is read off the form group, not off `AjfFieldInstance.value`: the
1432
+ * instance's own `value` is only written at initialisation and by formulas, so it
1433
+ * does not follow what the user types. The group is flat and keyed by each
1434
+ * instance's complete name, which is how `AjfFormRendererService.getControl`
1435
+ * resolves a control too.
1436
+ */
1437
+ const isFilled = (field, formGroup) => {
1438
+ const name = nodeInstanceCompleteName(field);
1439
+ const control = formGroup != null && formGroup.contains(name) ? formGroup.controls[name] : null;
1440
+ const value = control != null ? control.value : field.value;
1441
+ if (value == null || value === '') {
1442
+ return false;
1443
+ }
1444
+ if (Array.isArray(value)) {
1445
+ return value.length > 0;
1446
+ }
1447
+ return true;
1448
+ };
1449
+ /**
1450
+ * How many of a slide's fields carry a value, out of how many are on it. Notes
1451
+ * (`AjfFieldType.Empty`) hold no value and are left out of both numbers.
1452
+ *
1453
+ * Impure because it reads mutable instance state, in the same way as
1454
+ * `ajfValidSlide` and `ajfAsFieldInstanceErrors`. Returns a memoized object; see
1455
+ * the note inside.
1456
+ */
1457
+ class AjfSlideCompletionPipe {
1458
+ constructor() {
1459
+ this._last = null;
1460
+ }
1461
+ transform(slide, idx = 0, formGroup = null) {
1462
+ const fields = countableFields(slide, idx);
1463
+ const done = fields.filter(f => isFilled(f, formGroup)).length;
1464
+ const total = fields.length;
1465
+ // Hand back the same object while the counts hold, or the fresh identity on
1466
+ // every check would trip Angular's "expression has changed" guard.
1467
+ if (this._last != null && this._last.done === done && this._last.total === total) {
1468
+ return this._last;
1469
+ }
1470
+ this._last = { done, total };
1471
+ return this._last;
1472
+ }
1473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideCompletionPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1474
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideCompletionPipe, name: "ajfSlideCompletion", pure: false }); }
1475
+ }
1476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideCompletionPipe, decorators: [{
1477
+ type: Pipe,
1478
+ args: [{ name: 'ajfSlideCompletion', pure: false }]
1479
+ }] });
1480
+ /**
1481
+ * How many of a slide's visible fields are failing validation.
1482
+ */
1483
+ class AjfSlideIssuesPipe {
1484
+ transform(slide, idx = 0) {
1485
+ return countableFields(slide, idx).filter(f => !f.valid).length;
1486
+ }
1487
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideIssuesPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1488
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideIssuesPipe, name: "ajfSlideIssues", pure: false }); }
1489
+ }
1490
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfSlideIssuesPipe, decorators: [{
1491
+ type: Pipe,
1492
+ args: [{ name: 'ajfSlideIssues', pure: false }]
1493
+ }] });
1494
+ /**
1495
+ * The form's outstanding work in one place. A per-slide count only tells the
1496
+ * reader about the slide they are already looking at, which is the one place
1497
+ * they can see the failing fields for themselves.
1498
+ *
1499
+ * Counted here rather than taken from `AjfFormRendererService.errors`, which
1500
+ * counts invalid slide pages and says nothing about how many fields are behind
1501
+ * them.
1502
+ *
1503
+ * Impure and memoized, like its neighbours above.
1504
+ */
1505
+ class AjfFormIssuesPipe {
1506
+ constructor() {
1507
+ this._last = { fields: 0, slides: 0 };
1508
+ }
1509
+ transform(slides) {
1510
+ let fields = 0;
1511
+ let slideCount = 0;
1512
+ (slides || [])
1513
+ .filter(slide => slide.visible !== false)
1514
+ .forEach(slide => {
1515
+ // Every repetition of a repeating slide carries its own set of fields,
1516
+ // and any of them can be the one failing.
1517
+ const reps = isRepeatingSlideInstance(slide)
1518
+ ? Math.max(1, slide.reps)
1519
+ : 1;
1520
+ let slideFields = 0;
1521
+ for (let idx = 0; idx < reps; idx++) {
1522
+ slideFields += countableFields(slide, idx).filter(f => !f.valid).length;
1523
+ }
1524
+ if (slideFields > 0) {
1525
+ fields += slideFields;
1526
+ slideCount++;
1527
+ }
1528
+ });
1529
+ if (this._last.fields === fields && this._last.slides === slideCount) {
1530
+ return this._last;
1531
+ }
1532
+ this._last = { fields, slides: slideCount };
1533
+ return this._last;
1534
+ }
1535
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormIssuesPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1536
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AjfFormIssuesPipe, name: "ajfFormIssues", pure: false }); }
1537
+ }
1538
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormIssuesPipe, decorators: [{
1539
+ type: Pipe,
1540
+ args: [{ name: 'ajfFormIssues', pure: false }]
1541
+ }] });
1542
+
1040
1543
  /**
1041
1544
  * @license
1042
1545
  * Copyright (C) Gnucoop soc. coop.
@@ -1061,9 +1564,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1061
1564
  class AjfFormRenderer extends AjfFormRenderer$1 {
1062
1565
  constructor(rendererService, changeDetectorRef) {
1063
1566
  super(rendererService, changeDetectorRef);
1567
+ /**
1568
+ * @deprecated The slide strip has been replaced by the jump menu in the slide
1569
+ * header, which is always available. Kept so that existing templates still
1570
+ * compile.
1571
+ */
1064
1572
  this.topBar = false;
1573
+ /**
1574
+ * @deprecated Field rows align their labels and controls on a shared grid, so
1575
+ * there is nothing left to centre.
1576
+ */
1065
1577
  this.centeredFieldsContent = false;
1578
+ /** How many field rows sit side by side. */
1066
1579
  this.maxColumns = 1;
1580
+ /**
1581
+ * The page the slider is showing. The slide header is rendered once, above the
1582
+ * slider, so it needs to know which slide is on screen; the page slider only
1583
+ * reports that imperatively, hence the mirrored property.
1584
+ */
1585
+ this.currentPage = 0;
1586
+ this._slideList = [];
1587
+ this._validitySubscription = Subscription.EMPTY;
1588
+ this._slidesSubscription = Subscription.EMPTY;
1589
+ this._valueSubscription = Subscription.EMPTY;
1590
+ this._pageSubscription = Subscription.EMPTY;
1591
+ this._pageInit = false;
1592
+ this._slidesSubscription = this.slides.subscribe(slides => {
1593
+ this._slideList = slides || [];
1594
+ });
1595
+ // This component is OnPush, and children are only visited when it is
1596
+ // checked. The slide header reports live state -- how many fields are
1597
+ // filled, how many are failing -- so a value change anywhere in the form has
1598
+ // to bring the renderer back into the check.
1599
+ this._valueSubscription = this.formGroup
1600
+ .pipe(switchMap(fg => (fg ? fg.valueChanges : EMPTY)))
1601
+ .subscribe(() => this._changeDetectorRef.markForCheck());
1602
+ // Validity moves without a value moving with it -- a visibility change or a
1603
+ // recalculated formula is enough -- and the issue counts are read through
1604
+ // impure pipes, so this brings the renderer back into the check too.
1605
+ this._validitySubscription = this.errors.subscribe(() => this._changeDetectorRef.markForCheck());
1606
+ }
1607
+ ngAfterViewChecked() {
1608
+ super.ngAfterViewChecked();
1609
+ if (!this._pageInit && this.formSlider != null) {
1610
+ this._pageInit = true;
1611
+ this.currentPage = this.formSlider.currentPage;
1612
+ this._pageSubscription = this.formSlider.pageScrollFinish.subscribe(() => {
1613
+ this.currentPage = this.formSlider.currentPage;
1614
+ this._changeDetectorRef.markForCheck();
1615
+ });
1616
+ }
1617
+ }
1618
+ ngOnDestroy() {
1619
+ this._slidesSubscription.unsubscribe();
1620
+ this._valueSubscription.unsubscribe();
1621
+ this._validitySubscription.unsubscribe();
1622
+ this._pageSubscription.unsubscribe();
1623
+ super.ngOnDestroy();
1067
1624
  }
1068
1625
  fieldStyle(field) {
1069
1626
  if (field.node.fieldType === AjfFieldType.Formula && field.node.label === '') {
@@ -1071,13 +1628,52 @@ class AjfFormRenderer extends AjfFormRenderer$1 {
1071
1628
  }
1072
1629
  return {};
1073
1630
  }
1074
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormRenderer, deps: [{ token: i1.AjfFormRendererService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1075
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfFormRenderer, selector: "ajf-form", inputs: { topBar: "topBar", centeredFieldsContent: "centeredFieldsContent", maxColumns: "maxColumns" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"formGroup|async as fg\">\n <form [class.ajf-form-readonly]=\"readonly\" novalidate [formGroup]=\"fg!\">\n <div class=\"ajf-form-container\">\n <mat-toolbar *ngIf=\"!hideTopToolbar && topBar\" class=\"ajf-btn-strip\">\n <mat-button-toggle-group>\n <ng-container\n *ngFor=\"let slideInstance of (slides|async); let idx = index; trackBy: trackNodeById\"\n >\n <mat-button-toggle\n *ngIf=\"slideInstance.node.label && slideInstance.node.label.length > 0\"\n class=\"ajf-topbar-button\"\n (click)=\"scrollToSlide(slideInstance)\"\n [checked]=\"isSlideToggleChecked(slideInstance, formSlider.currentPage)\"\n [disabled]=\"slideInstance.visible === false\"\n >\n {{slideInstance.node.label | transloco}} {{ getRepeatingSlideRepIndex(slideInstance,\n formSlider.currentPage)|async}}\n <mat-icon\n *ngIf=\"!slideInstance.valid && slideInstance.visible !== false\"\n class=\"ajf-warning\"\n >warning</mat-icon\n >\n <mat-icon\n *ngIf=\"slideInstance.valid && slideInstance.visible !== false\"\n class=\"ajf-success\"\n >check</mat-icon\n >\n </mat-button-toggle>\n </ng-container>\n </mat-button-toggle-group>\n </mat-toolbar>\n <mat-toolbar *ngIf=\"!hideTopToolbar\">\n {{ title }}\n <span class=\"ajf-spacer\"></span>\n <!-- this content projection allow to add buttons on toolbar -->\n <ng-content select=\"[ajfFormTopToolbarButtons]\"></ng-content>\n <!-- apply a default save button only when ajfFormSaveButton is empty -->\n <span *ngIf=\"!saveDisabled\" (click)=\"onSave($event)\">\n <span #saveButton><ng-content select=\"[ajfFormSaveButton]\"></ng-content></span>\n <button\n *ngIf=\"saveButton && saveButton.childNodes && saveButton.childNodes.length === 0\"\n mat-button\n default\n >\n {{'Save'|transloco}}\n </button>\n </span>\n </mat-toolbar>\n <div class=\"ajf-slider-container\">\n <ajf-page-slider\n (orientationChange)=\"orientationChangeHandler($event)\"\n [fixedOrientation]=\"fixedOrientation\"\n [hideNavigationButtons]=\"hideNavigationButtons\"\n [orientation]=\"orientation\"\n #formSlider\n >\n <ng-container *ngIf=\"(slides|async) as curSlides\">\n <ng-container *ngIf=\"curSlides!.length > 0 && hasStartMessage\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span class=\"ajf-form-header-number\"> 1 &rarr; </span>\n <span class=\"ajf-title\">\n <ng-content select=\"[ajfFormStartMessageTitle]\"></ng-content>\n </span>\n </h2>\n </div>\n </mat-card-header>\n <mat-card-content>\n <ng-content select=\"[ajfFormStartMessage]\"></ng-content>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n <ng-container *ngFor=\"let slideInstance of curSlides; trackBy:trackNodeById\">\n <!-- non repeating slides -->\n <ng-container *ngIf=\"slideInstance.visible\">\n <ng-container *ngIf=\"!(slideInstance|ajfIsRepeatingSlideInstance)\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span class=\"ajf-form-header-number\"\n >{{ slideInstance.position + (hasStartMessage | ajfBoolToInt) }}\n &rarr;</span\n >\n <span [innerHTML]=\"slideInstance.node.label | transloco\"></span>\n </h2>\n <mat-icon class=\"ajf-warning\" *ngIf=\"!slideInstance.valid\"\n >warning</mat-icon\n >\n <mat-icon class=\"ajf-success\" *ngIf=\"slideInstance.valid\"\n >check</mat-icon\n >\n </div>\n </mat-card-header>\n <mat-card-content>\n <ng-template\n ngFor\n let-fieldInstance\n [ngForOf]=\"slideInstance.flatNodes\"\n [ngForTrackBy]=\"trackNodeById\"\n >\n <mat-card\n appearance=\"outlined\"\n [ngClass]=\"'ajf-' + (fieldInstance|ajfAsFieldInstance).node.size +\n ' ajf-max-columns-' + maxColumns +\n (centeredFieldsContent ? ' ajf-centered-field' : '')\"\n class=\"ajf-field-entry\"\n *ngIf=\"fieldInstance.visible\"\n [ngStyle]=\"fieldStyle(fieldInstance|ajfAsFieldInstance)\"\n >\n <i\n [class]=\"(fieldInstance|ajfAsFieldInstance).node.fieldType | ajfFieldIcon\"\n item-right\n ></i>\n <p>\n {{ ((fieldInstance|ajfAsFieldInstance).node.description || '') |\n transloco }}\n </p>\n\n <mat-card-header>\n <mat-card-title>\n <label\n [attr.id]=\"fieldInstance.node.name\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node.fieldType !== 7\"\n [innerHTML]=\"fieldInstance.node.label | transloco\"\n ></label>\n </mat-card-title>\n <mat-icon\n class=\"ajf-tooltip-icon\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node?.hint as hint\"\n [matTooltip]=\"hint | transloco\"\n matTooltipPosition=\"right\"\n >\n {{(fieldInstance|ajfAsFieldInstance).node.hintIcon ||\n 'help'}}</mat-icon\n ></mat-card-header\n >\n <mat-card-content>\n <ajf-field\n [instance]=\"fieldInstance|ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n [id]=\"'field_entry_' + fieldInstance.node.id\"\n >\n </ajf-field>\n </mat-card-content>\n <mat-card-actions\n [ngClass]=\"(fieldInstance|ajfAsFieldInstance)?.valid ?\n 'ajf-valid-field'\n : 'ajf-invalid-field'\"\n >\n <ng-container\n *ngIf=\"(fieldInstance|ajfAsFieldInstance)?.valid !== true; else ajfValidFieldTemplate\"\n >\n <span class=\"ajf-field-error-message\"\n >{{(fieldInstance|ajfAsFieldInstanceErrors|transloco)}}</span\n >\n <mat-icon class=\"ajf-warning\">warning</mat-icon>\n </ng-container>\n <ng-template #ajfValidFieldTemplate>\n <mat-icon class=\"ajf-success\">check</mat-icon>\n </ng-template>\n </mat-card-actions>\n </mat-card>\n </ng-template>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n <!-- repeating slides -->\n <ng-container *ngIf=\"(slideInstance|ajfIsRepeatingSlideInstance)\">\n <ajf-page-slider-item\n *ngFor=\"let curRep of ((slideInstance|ajfAsRepeatingSlideInstance).reps|ajfRange); let idx = index; let lastSlide = last\"\n [isRepeating]=\"true\"\n [isRepeatingLast]=\"lastSlide\"\n >\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span class=\"ajf-form-header-number\"\n >{{ slideInstance.position|ajfIncrement:idx + (hasStartMessage |\n ajfBoolToInt) }} &rarr;</span\n >\n <span [innerHTML]=\"slideInstance.node.label | transloco\"></span>\n </h2>\n <mat-icon class=\"ajf-warning\" *ngIf=\"!(slideInstance|ajfValidSlide:idx)\"\n >warning</mat-icon\n >\n <mat-icon class=\"ajf-success\" *ngIf=\"(slideInstance|ajfValidSlide:idx)\"\n >check</mat-icon\n >\n </div>\n </mat-card-header>\n <mat-card-content>\n <div *ngIf=\"!readonly\" class=\"ajf-group-actions\">\n <button\n *ngIf=\"lastSlide\"\n (click)=\"addGroup(slideInstance)\"\n [disabled]=\"!(slideInstance|ajfAsRepeatingSlideInstance).canAdd || ((slideInstance|ajfAsRepeatingSlideInstance).node.disableRemoval && !slideInstance.valid)\"\n mat-mini-fab\n >\n <mat-icon>add</mat-icon>\n </button>\n <button\n (click)=\"removeGroup(slideInstance, idx)\"\n [disabled]=\"!(slideInstance|ajfAsRepeatingSlideInstance).canRemove || (slideInstance|ajfAsRepeatingSlideInstance).node.disableRemoval\"\n mat-mini-fab\n >\n <mat-icon>remove</mat-icon>\n </button>\n </div>\n <ng-template\n ngFor\n let-fieldInstance\n [ngForOf]=\"slideInstance.slideNodes[idx]\"\n [ngForTrackBy]=\"trackNodeById\"\n >\n <mat-card\n appearance=\"outlined\"\n [ngClass]=\"'ajf-' + (fieldInstance|ajfAsFieldInstance).node.size +\n ' ajf-max-columns-' + maxColumns +\n (centeredFieldsContent ? ' ajf-centered-field' : '')\"\n class=\"ajf-field-entry\"\n *ngIf=\"fieldInstance.visible\"\n [ngStyle]=\"fieldStyle(fieldInstance|ajfAsFieldInstance)\"\n >\n <i\n [class]=\"(fieldInstance|ajfAsFieldInstance).node.fieldType | ajfFieldIcon\"\n item-right\n ></i>\n <p>\n {{ ((fieldInstance|ajfAsFieldInstance).node.description || '') |\n transloco }}\n </p>\n\n <mat-card-header>\n <mat-card-title>\n <label\n [attr.id]=\"fieldInstance.node.name\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node.fieldType !== 7\"\n [innerHTML]=\"fieldInstance.node.label | transloco\"\n ></label>\n </mat-card-title>\n <mat-icon\n class=\"ajf-tooltip-icon\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node?.hint as hint\"\n [matTooltip]=\"hint | transloco\"\n matTooltipPosition=\"right\"\n >\n {{(fieldInstance|ajfAsFieldInstance).node.hintIcon ||\n 'help'}}</mat-icon\n ></mat-card-header\n >\n <mat-card-content>\n <ajf-field\n [instance]=\"fieldInstance|ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n [id]=\"'field_entry_' + fieldInstance.node.id\"\n >\n </ajf-field>\n </mat-card-content>\n <mat-card-actions\n [ngClass]=\"(fieldInstance|ajfAsFieldInstance)?.valid ?\n 'ajf-valid-field'\n : 'ajf-invalid-field'\"\n >\n <ng-container\n *ngIf=\"(fieldInstance|ajfAsFieldInstance)?.valid !== true; else ajfValidFieldTemplate\"\n >\n <span class=\"ajf-field-error-message\"\n >{{(fieldInstance|ajfAsFieldInstanceErrors)}}</span\n >\n <mat-icon class=\"ajf-warning\">warning</mat-icon>\n </ng-container>\n <ng-template #ajfValidFieldTemplate>\n <mat-icon class=\"ajf-success\">check</mat-icon>\n </ng-template>\n </mat-card-actions>\n </mat-card>\n </ng-template>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"curSlides && curSlides!.length > 0 && hasEndMessage\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span *ngIf=\"(slidesNum|async) as snum\" class=\"ajf-form-header-number\">\n {{ snum! + (hasStartMessage | ajfBoolToInt ) + 1 }} &rarr;\n </span>\n <span class=\"ajf-title\">\n <ng-content select=\"[ajfFormEndMessageTitle]\"></ng-content>\n </span>\n </h2>\n </div>\n </mat-card-header>\n <mat-card-content>\n <ng-content select=\"[ajfFormEndMessage]\"></ng-content>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n </ng-container>\n <div ajfPageSliderBar *ngIf=\"!hideBottomToolbar\">\n <div class=\"ajf-left-bar\">\n <div class=\"ajf-errors\" *ngIf=\"((errors | async) || 0) > 0\">\n <button mat-button (click)=\"goToPrevError()\" danger>\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button mat-button (click)=\"goToNextError()\" danger>\n <mat-icon>arrow_downward</mat-icon>\n </button>\n </div>\n <div class=\"ajf-info-box ajf-error\">\n <div class=\"ajf-title\">{{'Errors'|transloco}}</div>\n <div class=\"ajf-content\">{{ errors | async }} / {{ slidesNum|async }}</div>\n </div>\n </div>\n </div>\n </ajf-page-slider>\n </div>\n </div>\n </form>\n</ng-container>\n", styles: ["ajf-form{display:block}ajf-form .ajf-form-readonly .ajf-field-entry>label{font-weight:700}ajf-form .ajf-form-container{display:flex;flex-direction:column;position:absolute;inset:0}ajf-form .ajf-form-container mat-toolbar.ajf-hidden{opacity:0}ajf-form .ajf-form-container .ajf-btn-strip .mat-button-toggle-group{overflow-x:auto}ajf-form .ajf-form-container .ajf-topbar-button{font-size:.8em}ajf-form .ajf-form-container mat-icon.ajf-warning{color:#f53d3d}ajf-form .ajf-form-container mat-icon.ajf-success{color:#32db64}ajf-form .ajf-form-container>.ajf-slider-container{flex:1;position:relative}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider{height:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content{padding:16px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page{flex:1;max-height:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card{margin:1em 0 3em}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content{display:flex;flex-wrap:wrap;flex-direction:row;align-content:flex-start;position:relative}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content .ajf-group-actions{position:absolute;right:0;top:-30px;padding:15px;z-index:10}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry{padding-right:10px;min-width:350px;display:flex;flex-direction:column;margin:5px;border-left:3px solid;border-radius:5px;min-height:30vh;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-icon{vertical-align:bottom;margin-left:5px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-max-columns-1{flex:1 0 100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-max-columns-2{flex:1 0 45%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-max-columns-3{flex:1 0 30%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-normal{width:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-small{width:50%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-smaller{width:33%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-tiny{width:25%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-mini{width:20%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions{position:absolute;bottom:0;width:100%;display:flex;justify-content:flex-start;align-items:center;align-content:center;border-bottom-left-radius:5px;border-bottom-right-radius:5px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions.ajf-valid-field{background-color:#32db6433}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions.ajf-invalid-field{background-color:#f53d3d33}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions.ajf-invalid-field .ajf-field-error-message{margin-left:8px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions .mat-icon{margin-left:auto}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-radio-button,ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry ajf-checkbox-group-item .mat-mdc-button{background-color:inherit!important}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-header{margin-bottom:15px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-header .ajf-tooltip-icon{align-self:center;min-width:24px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content{position:relative;flex:1;flex-flow:row wrap;justify-content:flex-start;align-items:flex-start;padding-top:2%;padding-bottom:10%;overflow-y:auto;max-width:95%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .mat-mdc-select{margin:20px 0}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .mat-mdc-radio-group{display:flex;flex-flow:column wrap;justify-content:space-between}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 30%;padding:5px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .ajf-errors .error{display:none}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-centered-field .mat-mdc-card-content,ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-centered-field .mat-mdc-card-header{justify-content:center;text-align:center}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-centered-field .ajf-choices-container .mat-mdc-radio-button{text-align:start}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .ajf-field-range{margin-top:30px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header{display:flex;align-items:center;width:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header>h2{flex:1}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header>h2>.ajf-form-header-number{margin-right:.5em}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header h2>.ajf-title{display:inline-block;margin-right:40px;white-space:normal;vertical-align:top}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar{display:flex;align-items:flex-start;flex-direction:row;position:absolute;bottom:0}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-right-button{float:right}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-button-icon-only ion-icon{padding:0 .1em}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box{height:40px;padding:4px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box>div{height:16px;line-height:16px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box>div.ajf-content{font-weight:700}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box.ajf-error{order:2;color:red}ajf-form .ajf-form-container .ajf-spacer{flex:1 0 auto}\n"], dependencies: [{ kind: "component", type: i2$a.AjfPageSliderItem, selector: "ajf-page-slider-item", inputs: ["isRepeating", "isRepeatingLast"], outputs: ["scroll"] }, { kind: "component", type: i3$5.AjfPageSlider, selector: "ajf-page-slider" }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i5.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }, { kind: "directive", type: i6$2.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i6$2.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: i7.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i7.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i7.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i7.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i7.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i3$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: AjfFormField, selector: "ajf-field,ajf-form-field" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.AjfAsFieldInstancePipe, name: "ajfAsFieldInstance" }, { kind: "pipe", type: i1.AjfAsFieldInstanceErrorsPipe, name: "ajfAsFieldInstanceErrors" }, { kind: "pipe", type: i1.AjfAsRepeatingSlideInstancePipe, name: "ajfAsRepeatingSlideInstance" }, { kind: "pipe", type: i1.AjfBoolToIntPipe, name: "ajfBoolToInt" }, { kind: "pipe", type: i1.AjfFieldIconPipe, name: "ajfFieldIcon" }, { kind: "pipe", type: i1.AjfIncrementPipe, name: "ajfIncrement" }, { kind: "pipe", type: i1.AjfIsRepeatingSlideInstancePipe, name: "ajfIsRepeatingSlideInstance" }, { kind: "pipe", type: i1.AjfRangePipe, name: "ajfRange" }, { kind: "pipe", type: i1.AjfValidSlidePipe, name: "ajfValidSlide" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1631
+ /** Page to the first page of a slide, from the header's jump menu. */
1632
+ goToSlide(slide) {
1633
+ this._slideTo(this._pageOf(slide));
1634
+ }
1635
+ /** Page to one repetition of the repeating slide currently on screen. */
1636
+ goToRep(slide, repIndex) {
1637
+ this._slideTo(this._pageOf(slide) + repIndex);
1638
+ }
1639
+ goToPrevSlide() {
1640
+ this.formSlider?.slide({ dir: 'up' });
1641
+ }
1642
+ goToNextSlide() {
1643
+ this.formSlider?.slide({ dir: 'down' });
1644
+ }
1645
+ /**
1646
+ * The slider page a slide starts on. `AjfSlideInstance.position` cannot be
1647
+ * used directly here: it does not account for a start message page, and this
1648
+ * has to agree with the page arithmetic used by `ajfCurrentSlide`.
1649
+ */
1650
+ _pageOf(slide) {
1651
+ let page = this.hasStartMessage ? 1 : 0;
1652
+ for (const cur of this._slideList) {
1653
+ if (cur.visible === false) {
1654
+ continue;
1655
+ }
1656
+ if (cur === slide) {
1657
+ break;
1658
+ }
1659
+ page += isRepeatingSlideInstance(cur)
1660
+ ? Math.max(1, cur.reps)
1661
+ : 1;
1662
+ }
1663
+ return page;
1664
+ }
1665
+ _slideTo(page) {
1666
+ if (this.formSlider != null) {
1667
+ this.formSlider.slide({ to: page });
1668
+ }
1669
+ }
1670
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormRenderer, deps: [{ token: i1$1.AjfFormRendererService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1671
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AjfFormRenderer, selector: "ajf-form", inputs: { topBar: "topBar", centeredFieldsContent: "centeredFieldsContent", maxColumns: "maxColumns" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"formGroup | async as fg\">\n <form [class.ajf-form-readonly]=\"readonly\" novalidate [formGroup]=\"fg!\">\n <div class=\"ajf-form-container\">\n <ng-container *ngIf=\"slides | async as curSlides\">\n <ng-container\n *ngIf=\"curSlides | ajfCurrentSlide : currentPage : hasStartMessage : hasEndMessage as cur\"\n >\n <div class=\"ajf-form-bar\" *ngIf=\"!hideTopToolbar\">\n <ajf-slide-header\n [slide]=\"cur.slide\"\n [slides]=\"curSlides\"\n [displayNumber]=\"cur.displayNumber\"\n [pages]=\"cur.pages\"\n (jumpTo)=\"goToSlide($event)\"\n (prev)=\"goToPrevSlide()\"\n (next)=\"goToNextSlide()\"\n >\n <!-- this content projection allows to add buttons on the slide header -->\n <ng-content select=\"[ajfFormTopToolbarButtons]\"></ng-content>\n <!-- The renderer has nowhere to save to: clicking here only emits\n `formAction`. So it ships no button of its own and holds the\n slot open instead -- a host that handles the event projects the\n button it wants, and gets the click through this wrapper. -->\n <span class=\"ajf-form-save\" *ngIf=\"!saveDisabled\" (click)=\"onSave($event)\">\n <ng-content select=\"[ajfFormSaveButton]\"></ng-content>\n </span>\n </ajf-slide-header>\n\n <ajf-rep-strip\n *ngIf=\"cur.slide && cur.reps > 0\"\n [slide]=\"cur.slide! | ajfAsRepeatingSlideInstance\"\n [current]=\"cur.repIndex\"\n [readonly]=\"readonly\"\n (goTo)=\"goToRep(cur.slide!, $event)\"\n (add)=\"addGroup(cur.slide!)\"\n (remove)=\"removeGroup(cur.slide!, cur.repIndex)\"\n ></ajf-rep-strip>\n </div>\n </ng-container>\n\n <div class=\"ajf-slider-container\">\n <ajf-page-slider\n (orientationChange)=\"orientationChangeHandler($event)\"\n [fixedOrientation]=\"fixedOrientation\"\n [hideNavigationButtons]=\"hideNavigationButtons\"\n [orientation]=\"orientation\"\n #formSlider\n >\n <ajf-page-slider-item *ngIf=\"curSlides!.length > 0 && hasStartMessage\">\n <div class=\"ajf-form-page ajf-form-message\">\n <h2 class=\"ajf-message-title\">\n <ng-content select=\"[ajfFormStartMessageTitle]\"></ng-content>\n </h2>\n <div class=\"ajf-message-body\">\n <ng-content select=\"[ajfFormStartMessage]\"></ng-content>\n </div>\n </div>\n </ajf-page-slider-item>\n\n <ng-container *ngFor=\"let slideInstance of curSlides; trackBy: trackNodeById\">\n <ng-container *ngIf=\"slideInstance.visible\">\n <!-- non repeating slides -->\n <ng-container *ngIf=\"!(slideInstance | ajfIsRepeatingSlideInstance)\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\" [ngClass]=\"'ajf-max-columns-' + maxColumns\">\n <ajf-field-row\n *ngFor=\"let fieldInstance of slideInstance.flatNodes; trackBy: trackNodeById\"\n [instance]=\"fieldInstance | ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n ></ajf-field-row>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n\n <!-- repeating slides: one page per repetition -->\n <ng-container *ngIf=\"slideInstance | ajfIsRepeatingSlideInstance\">\n <ajf-page-slider-item\n *ngFor=\"\n let curRep of (slideInstance | ajfAsRepeatingSlideInstance).reps | ajfRange;\n let idx = index;\n let lastSlide = last\n \"\n [isRepeating]=\"true\"\n [isRepeatingLast]=\"lastSlide\"\n >\n <div class=\"ajf-form-page\" [ngClass]=\"'ajf-max-columns-' + maxColumns\">\n <ajf-field-row\n *ngFor=\"\n let fieldInstance of slideInstance.slideNodes[idx];\n trackBy: trackNodeById\n \"\n [instance]=\"fieldInstance | ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n ></ajf-field-row>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ajf-page-slider-item *ngIf=\"curSlides && curSlides!.length > 0 && hasEndMessage\">\n <div class=\"ajf-form-page ajf-form-message\">\n <h2 class=\"ajf-message-title\">\n <ng-content select=\"[ajfFormEndMessageTitle]\"></ng-content>\n </h2>\n <div class=\"ajf-message-body\">\n <ng-content select=\"[ajfFormEndMessage]\"></ng-content>\n </div>\n </div>\n </ajf-page-slider-item>\n\n <div ajfPageSliderBar *ngIf=\"!hideBottomToolbar\" class=\"ajf-form-footer\">\n <ng-container *ngIf=\"curSlides | ajfFormIssues as issues\">\n <!-- The count is the control: reading that something needs\n attention and asking to be taken there is one intention, so\n it is one target rather than a label with arrows beside it. -->\n <button\n type=\"button\"\n class=\"ajf-form-footer-status\"\n *ngIf=\"issues.fields > 0\"\n (click)=\"goToNextError()\"\n >\n <mat-icon>error</mat-icon>\n <span class=\"ajf-form-footer-message\"\n >{{ '{{fields}} fields in {{slides}} slides need attention' | transloco :\n {fields: issues.fields, slides: issues.slides} }}</span\n >\n </button>\n </ng-container>\n\n <!-- Pushed to the far end of the bar by its auto margin, so it sits\n next to the slider's own paging buttons rather than next to the\n error status. -->\n <ng-container\n *ngIf=\"\n curSlides | ajfCurrentSlide : currentPage : hasStartMessage : hasEndMessage as cur\n \"\n >\n <span class=\"ajf-slide-count\" *ngIf=\"cur.pages > 1 && cur.total > 0\"\n >{{ 'slide' | transloco }} {{ cur.displayNumber }} {{ 'of' | transloco }} {{\n cur.total }}</span\n >\n </ng-container>\n </div>\n </ajf-page-slider>\n </div>\n </ng-container>\n </div>\n </form>\n</ng-container>\n", styles: ["ajf-form{display:block;height:100%}ajf-form .ajf-form-container{display:flex;flex-direction:column;box-sizing:border-box;height:100%;background:var(--ajf-bg);color:var(--ajf-text);font-family:var(--ajf-font-sans)}ajf-form .ajf-form-bar{flex:0 0 auto;border-bottom:1px solid var(--ajf-border);background:var(--ajf-surface)}ajf-form .ajf-form-save{display:inline-flex;align-items:center;gap:8px}ajf-form .ajf-form-save:empty{display:none}ajf-form>form{height:100%}ajf-form .ajf-slider-container{position:relative;flex:1 1 auto;min-height:var(--ajf-slider-min-h)}ajf-form .ajf-slider-container>ajf-page-slider{position:absolute;inset:0}ajf-form .ajf-form-page{display:flex;flex-direction:column;align-self:stretch;box-sizing:border-box;width:100%;background:var(--ajf-surface)}ajf-form .ajf-form-page.ajf-max-columns-2,ajf-form .ajf-form-page.ajf-max-columns-3{display:grid;align-content:start}ajf-form .ajf-form-page.ajf-max-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}ajf-form .ajf-form-page.ajf-max-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}@media (width <= 900px){ajf-form .ajf-form-page.ajf-max-columns-2,ajf-form .ajf-form-page.ajf-max-columns-3{grid-template-columns:minmax(0,1fr)}}ajf-form .ajf-form-message{gap:12px;padding:24px 20px}ajf-form .ajf-form-message .ajf-message-title{margin:0;font-size:20px;font-weight:600}ajf-form .ajf-form-message .ajf-message-body{color:var(--ajf-text-muted)}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar{flex-wrap:wrap;row-gap:4px;height:auto;min-height:48px;padding:6px 12px;white-space:normal;border-top:1px solid var(--ajf-border);background:var(--ajf-band);color:var(--ajf-text-muted);font-family:var(--ajf-font-sans);font-size:13px}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:36px;min-width:0;height:36px;min-height:0;padding:0;border:0;border-radius:50%;background:none;color:var(--ajf-text-muted);text-decoration:none}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button .mat-icon{width:18px;height:18px;margin:0;font-size:18px}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button:hover:not(:disabled){border-color:transparent;text-decoration:none}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button{--mat-text-button-state-layer-color: var(--ajf-text)}ajf-form .ajf-form-footer{display:contents}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar:has(.ajf-slide-count) .ajf-spacer{flex-grow:0}ajf-form .ajf-slide-count{font-family:var(--ajf-font-mono);margin-right:8px;margin-left:auto;color:var(--ajf-text-faint)}ajf-form .ajf-form-footer-status{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px;min-width:0;padding:0;border:0;background:none;color:var(--ajf-danger);font:inherit;text-align:left;cursor:pointer}ajf-form .ajf-form-footer-status .mat-icon{width:16px;height:16px;font-size:16px}ajf-form .ajf-form-footer-status:hover .ajf-form-footer-message,ajf-form .ajf-form-footer-status:focus-visible .ajf-form-footer-message{text-decoration:underline}ajf-form .ajf-form-readonly .ajf-field-label label{font-weight:600}\n"], dependencies: [{ kind: "component", type: i2$b.AjfPageSliderItem, selector: "ajf-page-slider-item", inputs: ["isRepeating", "isRepeatingLast"], outputs: ["scroll"] }, { kind: "component", type: i3$5.AjfPageSlider, selector: "ajf-page-slider" }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: AjfFieldRow, selector: "ajf-field-row", inputs: ["instance", "readonly"] }, { kind: "component", type: AjfRepStrip, selector: "ajf-rep-strip", inputs: ["slide", "current", "readonly"], outputs: ["goTo", "add", "remove"] }, { kind: "component", type: AjfSlideHeader, selector: "ajf-slide-header", inputs: ["slide", "displayNumber", "slides", "pages"], outputs: ["jumpTo", "prev", "next"] }, { kind: "pipe", type: i5.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.AjfAsFieldInstancePipe, name: "ajfAsFieldInstance" }, { kind: "pipe", type: i1$1.AjfAsRepeatingSlideInstancePipe, name: "ajfAsRepeatingSlideInstance" }, { kind: "pipe", type: i1$1.AjfIsRepeatingSlideInstancePipe, name: "ajfIsRepeatingSlideInstance" }, { kind: "pipe", type: i1$1.AjfRangePipe, name: "ajfRange" }, { kind: "pipe", type: AjfCurrentSlidePipe, name: "ajfCurrentSlide" }, { kind: "pipe", type: AjfFormIssuesPipe, name: "ajfFormIssues" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1076
1672
  }
1077
1673
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormRenderer, decorators: [{
1078
1674
  type: Component,
1079
- args: [{ selector: 'ajf-form', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"formGroup|async as fg\">\n <form [class.ajf-form-readonly]=\"readonly\" novalidate [formGroup]=\"fg!\">\n <div class=\"ajf-form-container\">\n <mat-toolbar *ngIf=\"!hideTopToolbar && topBar\" class=\"ajf-btn-strip\">\n <mat-button-toggle-group>\n <ng-container\n *ngFor=\"let slideInstance of (slides|async); let idx = index; trackBy: trackNodeById\"\n >\n <mat-button-toggle\n *ngIf=\"slideInstance.node.label && slideInstance.node.label.length > 0\"\n class=\"ajf-topbar-button\"\n (click)=\"scrollToSlide(slideInstance)\"\n [checked]=\"isSlideToggleChecked(slideInstance, formSlider.currentPage)\"\n [disabled]=\"slideInstance.visible === false\"\n >\n {{slideInstance.node.label | transloco}} {{ getRepeatingSlideRepIndex(slideInstance,\n formSlider.currentPage)|async}}\n <mat-icon\n *ngIf=\"!slideInstance.valid && slideInstance.visible !== false\"\n class=\"ajf-warning\"\n >warning</mat-icon\n >\n <mat-icon\n *ngIf=\"slideInstance.valid && slideInstance.visible !== false\"\n class=\"ajf-success\"\n >check</mat-icon\n >\n </mat-button-toggle>\n </ng-container>\n </mat-button-toggle-group>\n </mat-toolbar>\n <mat-toolbar *ngIf=\"!hideTopToolbar\">\n {{ title }}\n <span class=\"ajf-spacer\"></span>\n <!-- this content projection allow to add buttons on toolbar -->\n <ng-content select=\"[ajfFormTopToolbarButtons]\"></ng-content>\n <!-- apply a default save button only when ajfFormSaveButton is empty -->\n <span *ngIf=\"!saveDisabled\" (click)=\"onSave($event)\">\n <span #saveButton><ng-content select=\"[ajfFormSaveButton]\"></ng-content></span>\n <button\n *ngIf=\"saveButton && saveButton.childNodes && saveButton.childNodes.length === 0\"\n mat-button\n default\n >\n {{'Save'|transloco}}\n </button>\n </span>\n </mat-toolbar>\n <div class=\"ajf-slider-container\">\n <ajf-page-slider\n (orientationChange)=\"orientationChangeHandler($event)\"\n [fixedOrientation]=\"fixedOrientation\"\n [hideNavigationButtons]=\"hideNavigationButtons\"\n [orientation]=\"orientation\"\n #formSlider\n >\n <ng-container *ngIf=\"(slides|async) as curSlides\">\n <ng-container *ngIf=\"curSlides!.length > 0 && hasStartMessage\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span class=\"ajf-form-header-number\"> 1 &rarr; </span>\n <span class=\"ajf-title\">\n <ng-content select=\"[ajfFormStartMessageTitle]\"></ng-content>\n </span>\n </h2>\n </div>\n </mat-card-header>\n <mat-card-content>\n <ng-content select=\"[ajfFormStartMessage]\"></ng-content>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n <ng-container *ngFor=\"let slideInstance of curSlides; trackBy:trackNodeById\">\n <!-- non repeating slides -->\n <ng-container *ngIf=\"slideInstance.visible\">\n <ng-container *ngIf=\"!(slideInstance|ajfIsRepeatingSlideInstance)\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span class=\"ajf-form-header-number\"\n >{{ slideInstance.position + (hasStartMessage | ajfBoolToInt) }}\n &rarr;</span\n >\n <span [innerHTML]=\"slideInstance.node.label | transloco\"></span>\n </h2>\n <mat-icon class=\"ajf-warning\" *ngIf=\"!slideInstance.valid\"\n >warning</mat-icon\n >\n <mat-icon class=\"ajf-success\" *ngIf=\"slideInstance.valid\"\n >check</mat-icon\n >\n </div>\n </mat-card-header>\n <mat-card-content>\n <ng-template\n ngFor\n let-fieldInstance\n [ngForOf]=\"slideInstance.flatNodes\"\n [ngForTrackBy]=\"trackNodeById\"\n >\n <mat-card\n appearance=\"outlined\"\n [ngClass]=\"'ajf-' + (fieldInstance|ajfAsFieldInstance).node.size +\n ' ajf-max-columns-' + maxColumns +\n (centeredFieldsContent ? ' ajf-centered-field' : '')\"\n class=\"ajf-field-entry\"\n *ngIf=\"fieldInstance.visible\"\n [ngStyle]=\"fieldStyle(fieldInstance|ajfAsFieldInstance)\"\n >\n <i\n [class]=\"(fieldInstance|ajfAsFieldInstance).node.fieldType | ajfFieldIcon\"\n item-right\n ></i>\n <p>\n {{ ((fieldInstance|ajfAsFieldInstance).node.description || '') |\n transloco }}\n </p>\n\n <mat-card-header>\n <mat-card-title>\n <label\n [attr.id]=\"fieldInstance.node.name\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node.fieldType !== 7\"\n [innerHTML]=\"fieldInstance.node.label | transloco\"\n ></label>\n </mat-card-title>\n <mat-icon\n class=\"ajf-tooltip-icon\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node?.hint as hint\"\n [matTooltip]=\"hint | transloco\"\n matTooltipPosition=\"right\"\n >\n {{(fieldInstance|ajfAsFieldInstance).node.hintIcon ||\n 'help'}}</mat-icon\n ></mat-card-header\n >\n <mat-card-content>\n <ajf-field\n [instance]=\"fieldInstance|ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n [id]=\"'field_entry_' + fieldInstance.node.id\"\n >\n </ajf-field>\n </mat-card-content>\n <mat-card-actions\n [ngClass]=\"(fieldInstance|ajfAsFieldInstance)?.valid ?\n 'ajf-valid-field'\n : 'ajf-invalid-field'\"\n >\n <ng-container\n *ngIf=\"(fieldInstance|ajfAsFieldInstance)?.valid !== true; else ajfValidFieldTemplate\"\n >\n <span class=\"ajf-field-error-message\"\n >{{(fieldInstance|ajfAsFieldInstanceErrors|transloco)}}</span\n >\n <mat-icon class=\"ajf-warning\">warning</mat-icon>\n </ng-container>\n <ng-template #ajfValidFieldTemplate>\n <mat-icon class=\"ajf-success\">check</mat-icon>\n </ng-template>\n </mat-card-actions>\n </mat-card>\n </ng-template>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n <!-- repeating slides -->\n <ng-container *ngIf=\"(slideInstance|ajfIsRepeatingSlideInstance)\">\n <ajf-page-slider-item\n *ngFor=\"let curRep of ((slideInstance|ajfAsRepeatingSlideInstance).reps|ajfRange); let idx = index; let lastSlide = last\"\n [isRepeating]=\"true\"\n [isRepeatingLast]=\"lastSlide\"\n >\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span class=\"ajf-form-header-number\"\n >{{ slideInstance.position|ajfIncrement:idx + (hasStartMessage |\n ajfBoolToInt) }} &rarr;</span\n >\n <span [innerHTML]=\"slideInstance.node.label | transloco\"></span>\n </h2>\n <mat-icon class=\"ajf-warning\" *ngIf=\"!(slideInstance|ajfValidSlide:idx)\"\n >warning</mat-icon\n >\n <mat-icon class=\"ajf-success\" *ngIf=\"(slideInstance|ajfValidSlide:idx)\"\n >check</mat-icon\n >\n </div>\n </mat-card-header>\n <mat-card-content>\n <div *ngIf=\"!readonly\" class=\"ajf-group-actions\">\n <button\n *ngIf=\"lastSlide\"\n (click)=\"addGroup(slideInstance)\"\n [disabled]=\"!(slideInstance|ajfAsRepeatingSlideInstance).canAdd || ((slideInstance|ajfAsRepeatingSlideInstance).node.disableRemoval && !slideInstance.valid)\"\n mat-mini-fab\n >\n <mat-icon>add</mat-icon>\n </button>\n <button\n (click)=\"removeGroup(slideInstance, idx)\"\n [disabled]=\"!(slideInstance|ajfAsRepeatingSlideInstance).canRemove || (slideInstance|ajfAsRepeatingSlideInstance).node.disableRemoval\"\n mat-mini-fab\n >\n <mat-icon>remove</mat-icon>\n </button>\n </div>\n <ng-template\n ngFor\n let-fieldInstance\n [ngForOf]=\"slideInstance.slideNodes[idx]\"\n [ngForTrackBy]=\"trackNodeById\"\n >\n <mat-card\n appearance=\"outlined\"\n [ngClass]=\"'ajf-' + (fieldInstance|ajfAsFieldInstance).node.size +\n ' ajf-max-columns-' + maxColumns +\n (centeredFieldsContent ? ' ajf-centered-field' : '')\"\n class=\"ajf-field-entry\"\n *ngIf=\"fieldInstance.visible\"\n [ngStyle]=\"fieldStyle(fieldInstance|ajfAsFieldInstance)\"\n >\n <i\n [class]=\"(fieldInstance|ajfAsFieldInstance).node.fieldType | ajfFieldIcon\"\n item-right\n ></i>\n <p>\n {{ ((fieldInstance|ajfAsFieldInstance).node.description || '') |\n transloco }}\n </p>\n\n <mat-card-header>\n <mat-card-title>\n <label\n [attr.id]=\"fieldInstance.node.name\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node.fieldType !== 7\"\n [innerHTML]=\"fieldInstance.node.label | transloco\"\n ></label>\n </mat-card-title>\n <mat-icon\n class=\"ajf-tooltip-icon\"\n *ngIf=\"(fieldInstance|ajfAsFieldInstance).node?.hint as hint\"\n [matTooltip]=\"hint | transloco\"\n matTooltipPosition=\"right\"\n >\n {{(fieldInstance|ajfAsFieldInstance).node.hintIcon ||\n 'help'}}</mat-icon\n ></mat-card-header\n >\n <mat-card-content>\n <ajf-field\n [instance]=\"fieldInstance|ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n [id]=\"'field_entry_' + fieldInstance.node.id\"\n >\n </ajf-field>\n </mat-card-content>\n <mat-card-actions\n [ngClass]=\"(fieldInstance|ajfAsFieldInstance)?.valid ?\n 'ajf-valid-field'\n : 'ajf-invalid-field'\"\n >\n <ng-container\n *ngIf=\"(fieldInstance|ajfAsFieldInstance)?.valid !== true; else ajfValidFieldTemplate\"\n >\n <span class=\"ajf-field-error-message\"\n >{{(fieldInstance|ajfAsFieldInstanceErrors)}}</span\n >\n <mat-icon class=\"ajf-warning\">warning</mat-icon>\n </ng-container>\n <ng-template #ajfValidFieldTemplate>\n <mat-icon class=\"ajf-success\">check</mat-icon>\n </ng-template>\n </mat-card-actions>\n </mat-card>\n </ng-template>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"curSlides && curSlides!.length > 0 && hasEndMessage\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\">\n <mat-card appearance=\"outlined\">\n <mat-card-header>\n <div class=\"ajf-page-slider-item-header\">\n <h2>\n <span *ngIf=\"(slidesNum|async) as snum\" class=\"ajf-form-header-number\">\n {{ snum! + (hasStartMessage | ajfBoolToInt ) + 1 }} &rarr;\n </span>\n <span class=\"ajf-title\">\n <ng-content select=\"[ajfFormEndMessageTitle]\"></ng-content>\n </span>\n </h2>\n </div>\n </mat-card-header>\n <mat-card-content>\n <ng-content select=\"[ajfFormEndMessage]\"></ng-content>\n </mat-card-content>\n </mat-card>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n </ng-container>\n <div ajfPageSliderBar *ngIf=\"!hideBottomToolbar\">\n <div class=\"ajf-left-bar\">\n <div class=\"ajf-errors\" *ngIf=\"((errors | async) || 0) > 0\">\n <button mat-button (click)=\"goToPrevError()\" danger>\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button mat-button (click)=\"goToNextError()\" danger>\n <mat-icon>arrow_downward</mat-icon>\n </button>\n </div>\n <div class=\"ajf-info-box ajf-error\">\n <div class=\"ajf-title\">{{'Errors'|transloco}}</div>\n <div class=\"ajf-content\">{{ errors | async }} / {{ slidesNum|async }}</div>\n </div>\n </div>\n </div>\n </ajf-page-slider>\n </div>\n </div>\n </form>\n</ng-container>\n", styles: ["ajf-form{display:block}ajf-form .ajf-form-readonly .ajf-field-entry>label{font-weight:700}ajf-form .ajf-form-container{display:flex;flex-direction:column;position:absolute;inset:0}ajf-form .ajf-form-container mat-toolbar.ajf-hidden{opacity:0}ajf-form .ajf-form-container .ajf-btn-strip .mat-button-toggle-group{overflow-x:auto}ajf-form .ajf-form-container .ajf-topbar-button{font-size:.8em}ajf-form .ajf-form-container mat-icon.ajf-warning{color:#f53d3d}ajf-form .ajf-form-container mat-icon.ajf-success{color:#32db64}ajf-form .ajf-form-container>.ajf-slider-container{flex:1;position:relative}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider{height:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content{padding:16px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page{flex:1;max-height:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card{margin:1em 0 3em}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content{display:flex;flex-wrap:wrap;flex-direction:row;align-content:flex-start;position:relative}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content .ajf-group-actions{position:absolute;right:0;top:-30px;padding:15px;z-index:10}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry{padding-right:10px;min-width:350px;display:flex;flex-direction:column;margin:5px;border-left:3px solid;border-radius:5px;min-height:30vh;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-icon{vertical-align:bottom;margin-left:5px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-max-columns-1{flex:1 0 100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-max-columns-2{flex:1 0 45%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-max-columns-3{flex:1 0 30%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-normal{width:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-small{width:50%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-smaller{width:33%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-tiny{width:25%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-mini{width:20%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions{position:absolute;bottom:0;width:100%;display:flex;justify-content:flex-start;align-items:center;align-content:center;border-bottom-left-radius:5px;border-bottom-right-radius:5px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions.ajf-valid-field{background-color:#32db6433}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions.ajf-invalid-field{background-color:#f53d3d33}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions.ajf-invalid-field .ajf-field-error-message{margin-left:8px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-actions .mat-icon{margin-left:auto}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-radio-button,ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry ajf-checkbox-group-item .mat-mdc-button{background-color:inherit!important}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-header{margin-bottom:15px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-header .ajf-tooltip-icon{align-self:center;min-width:24px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content{position:relative;flex:1;flex-flow:row wrap;justify-content:flex-start;align-items:flex-start;padding-top:2%;padding-bottom:10%;overflow-y:auto;max-width:95%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .mat-mdc-select{margin:20px 0}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .mat-mdc-radio-group{display:flex;flex-flow:column wrap;justify-content:space-between}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 30%;padding:5px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .mat-mdc-card-content .ajf-errors .error{display:none}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-centered-field .mat-mdc-card-content,ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-centered-field .mat-mdc-card-header{justify-content:center;text-align:center}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry.ajf-centered-field .ajf-choices-container .mat-mdc-radio-button{text-align:start}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider ajf-page-slider-item .ajf-page-slider-item-content .ajf-form-page>mat-card>mat-card-content>.ajf-field-entry .ajf-field-range{margin-top:30px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header{display:flex;align-items:center;width:100%}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header>h2{flex:1}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header>h2>.ajf-form-header-number{margin-right:.5em}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider .ajf-page-slider-item-header h2>.ajf-title{display:inline-block;margin-right:40px;white-space:normal;vertical-align:top}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar{display:flex;align-items:flex-start;flex-direction:row;position:absolute;bottom:0}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-right-button{float:right}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-button-icon-only ion-icon{padding:0 .1em}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box{height:40px;padding:4px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box>div{height:16px;line-height:16px}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box>div.ajf-content{font-weight:700}ajf-form .ajf-form-container>.ajf-slider-container>ajf-page-slider [ajfPageSliderBar] .ajf-left-bar .ajf-info-box.ajf-error{order:2;color:red}ajf-form .ajf-form-container .ajf-spacer{flex:1 0 auto}\n"] }]
1080
- }], ctorParameters: () => [{ type: i1.AjfFormRendererService }, { type: i0.ChangeDetectorRef }], propDecorators: { topBar: [{
1675
+ args: [{ selector: 'ajf-form', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"formGroup | async as fg\">\n <form [class.ajf-form-readonly]=\"readonly\" novalidate [formGroup]=\"fg!\">\n <div class=\"ajf-form-container\">\n <ng-container *ngIf=\"slides | async as curSlides\">\n <ng-container\n *ngIf=\"curSlides | ajfCurrentSlide : currentPage : hasStartMessage : hasEndMessage as cur\"\n >\n <div class=\"ajf-form-bar\" *ngIf=\"!hideTopToolbar\">\n <ajf-slide-header\n [slide]=\"cur.slide\"\n [slides]=\"curSlides\"\n [displayNumber]=\"cur.displayNumber\"\n [pages]=\"cur.pages\"\n (jumpTo)=\"goToSlide($event)\"\n (prev)=\"goToPrevSlide()\"\n (next)=\"goToNextSlide()\"\n >\n <!-- this content projection allows to add buttons on the slide header -->\n <ng-content select=\"[ajfFormTopToolbarButtons]\"></ng-content>\n <!-- The renderer has nowhere to save to: clicking here only emits\n `formAction`. So it ships no button of its own and holds the\n slot open instead -- a host that handles the event projects the\n button it wants, and gets the click through this wrapper. -->\n <span class=\"ajf-form-save\" *ngIf=\"!saveDisabled\" (click)=\"onSave($event)\">\n <ng-content select=\"[ajfFormSaveButton]\"></ng-content>\n </span>\n </ajf-slide-header>\n\n <ajf-rep-strip\n *ngIf=\"cur.slide && cur.reps > 0\"\n [slide]=\"cur.slide! | ajfAsRepeatingSlideInstance\"\n [current]=\"cur.repIndex\"\n [readonly]=\"readonly\"\n (goTo)=\"goToRep(cur.slide!, $event)\"\n (add)=\"addGroup(cur.slide!)\"\n (remove)=\"removeGroup(cur.slide!, cur.repIndex)\"\n ></ajf-rep-strip>\n </div>\n </ng-container>\n\n <div class=\"ajf-slider-container\">\n <ajf-page-slider\n (orientationChange)=\"orientationChangeHandler($event)\"\n [fixedOrientation]=\"fixedOrientation\"\n [hideNavigationButtons]=\"hideNavigationButtons\"\n [orientation]=\"orientation\"\n #formSlider\n >\n <ajf-page-slider-item *ngIf=\"curSlides!.length > 0 && hasStartMessage\">\n <div class=\"ajf-form-page ajf-form-message\">\n <h2 class=\"ajf-message-title\">\n <ng-content select=\"[ajfFormStartMessageTitle]\"></ng-content>\n </h2>\n <div class=\"ajf-message-body\">\n <ng-content select=\"[ajfFormStartMessage]\"></ng-content>\n </div>\n </div>\n </ajf-page-slider-item>\n\n <ng-container *ngFor=\"let slideInstance of curSlides; trackBy: trackNodeById\">\n <ng-container *ngIf=\"slideInstance.visible\">\n <!-- non repeating slides -->\n <ng-container *ngIf=\"!(slideInstance | ajfIsRepeatingSlideInstance)\">\n <ajf-page-slider-item>\n <div class=\"ajf-form-page\" [ngClass]=\"'ajf-max-columns-' + maxColumns\">\n <ajf-field-row\n *ngFor=\"let fieldInstance of slideInstance.flatNodes; trackBy: trackNodeById\"\n [instance]=\"fieldInstance | ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n ></ajf-field-row>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n\n <!-- repeating slides: one page per repetition -->\n <ng-container *ngIf=\"slideInstance | ajfIsRepeatingSlideInstance\">\n <ajf-page-slider-item\n *ngFor=\"\n let curRep of (slideInstance | ajfAsRepeatingSlideInstance).reps | ajfRange;\n let idx = index;\n let lastSlide = last\n \"\n [isRepeating]=\"true\"\n [isRepeatingLast]=\"lastSlide\"\n >\n <div class=\"ajf-form-page\" [ngClass]=\"'ajf-max-columns-' + maxColumns\">\n <ajf-field-row\n *ngFor=\"\n let fieldInstance of slideInstance.slideNodes[idx];\n trackBy: trackNodeById\n \"\n [instance]=\"fieldInstance | ajfAsFieldInstance\"\n [readonly]=\"readonly || !slideInstance.editable\"\n ></ajf-field-row>\n </div>\n </ajf-page-slider-item>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ajf-page-slider-item *ngIf=\"curSlides && curSlides!.length > 0 && hasEndMessage\">\n <div class=\"ajf-form-page ajf-form-message\">\n <h2 class=\"ajf-message-title\">\n <ng-content select=\"[ajfFormEndMessageTitle]\"></ng-content>\n </h2>\n <div class=\"ajf-message-body\">\n <ng-content select=\"[ajfFormEndMessage]\"></ng-content>\n </div>\n </div>\n </ajf-page-slider-item>\n\n <div ajfPageSliderBar *ngIf=\"!hideBottomToolbar\" class=\"ajf-form-footer\">\n <ng-container *ngIf=\"curSlides | ajfFormIssues as issues\">\n <!-- The count is the control: reading that something needs\n attention and asking to be taken there is one intention, so\n it is one target rather than a label with arrows beside it. -->\n <button\n type=\"button\"\n class=\"ajf-form-footer-status\"\n *ngIf=\"issues.fields > 0\"\n (click)=\"goToNextError()\"\n >\n <mat-icon>error</mat-icon>\n <span class=\"ajf-form-footer-message\"\n >{{ '{{fields}} fields in {{slides}} slides need attention' | transloco :\n {fields: issues.fields, slides: issues.slides} }}</span\n >\n </button>\n </ng-container>\n\n <!-- Pushed to the far end of the bar by its auto margin, so it sits\n next to the slider's own paging buttons rather than next to the\n error status. -->\n <ng-container\n *ngIf=\"\n curSlides | ajfCurrentSlide : currentPage : hasStartMessage : hasEndMessage as cur\n \"\n >\n <span class=\"ajf-slide-count\" *ngIf=\"cur.pages > 1 && cur.total > 0\"\n >{{ 'slide' | transloco }} {{ cur.displayNumber }} {{ 'of' | transloco }} {{\n cur.total }}</span\n >\n </ng-container>\n </div>\n </ajf-page-slider>\n </div>\n </ng-container>\n </div>\n </form>\n</ng-container>\n", styles: ["ajf-form{display:block;height:100%}ajf-form .ajf-form-container{display:flex;flex-direction:column;box-sizing:border-box;height:100%;background:var(--ajf-bg);color:var(--ajf-text);font-family:var(--ajf-font-sans)}ajf-form .ajf-form-bar{flex:0 0 auto;border-bottom:1px solid var(--ajf-border);background:var(--ajf-surface)}ajf-form .ajf-form-save{display:inline-flex;align-items:center;gap:8px}ajf-form .ajf-form-save:empty{display:none}ajf-form>form{height:100%}ajf-form .ajf-slider-container{position:relative;flex:1 1 auto;min-height:var(--ajf-slider-min-h)}ajf-form .ajf-slider-container>ajf-page-slider{position:absolute;inset:0}ajf-form .ajf-form-page{display:flex;flex-direction:column;align-self:stretch;box-sizing:border-box;width:100%;background:var(--ajf-surface)}ajf-form .ajf-form-page.ajf-max-columns-2,ajf-form .ajf-form-page.ajf-max-columns-3{display:grid;align-content:start}ajf-form .ajf-form-page.ajf-max-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}ajf-form .ajf-form-page.ajf-max-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}@media (width <= 900px){ajf-form .ajf-form-page.ajf-max-columns-2,ajf-form .ajf-form-page.ajf-max-columns-3{grid-template-columns:minmax(0,1fr)}}ajf-form .ajf-form-message{gap:12px;padding:24px 20px}ajf-form .ajf-form-message .ajf-message-title{margin:0;font-size:20px;font-weight:600}ajf-form .ajf-form-message .ajf-message-body{color:var(--ajf-text-muted)}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar{flex-wrap:wrap;row-gap:4px;height:auto;min-height:48px;padding:6px 12px;white-space:normal;border-top:1px solid var(--ajf-border);background:var(--ajf-band);color:var(--ajf-text-muted);font-family:var(--ajf-font-sans);font-size:13px}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:36px;min-width:0;height:36px;min-height:0;padding:0;border:0;border-radius:50%;background:none;color:var(--ajf-text-muted);text-decoration:none}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button .mat-icon{width:18px;height:18px;margin:0;font-size:18px}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button:hover:not(:disabled){border-color:transparent;text-decoration:none}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar .mat-mdc-button{--mat-text-button-state-layer-color: var(--ajf-text)}ajf-form .ajf-form-footer{display:contents}ajf-form ajf-page-slider>mat-toolbar.ajf-toolbar:has(.ajf-slide-count) .ajf-spacer{flex-grow:0}ajf-form .ajf-slide-count{font-family:var(--ajf-font-mono);margin-right:8px;margin-left:auto;color:var(--ajf-text-faint)}ajf-form .ajf-form-footer-status{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px;min-width:0;padding:0;border:0;background:none;color:var(--ajf-danger);font:inherit;text-align:left;cursor:pointer}ajf-form .ajf-form-footer-status .mat-icon{width:16px;height:16px;font-size:16px}ajf-form .ajf-form-footer-status:hover .ajf-form-footer-message,ajf-form .ajf-form-footer-status:focus-visible .ajf-form-footer-message{text-decoration:underline}ajf-form .ajf-form-readonly .ajf-field-label label{font-weight:600}\n"] }]
1676
+ }], ctorParameters: () => [{ type: i1$1.AjfFormRendererService }, { type: i0.ChangeDetectorRef }], propDecorators: { topBar: [{
1081
1677
  type: Input
1082
1678
  }], centeredFieldsContent: [{
1083
1679
  type: Input
@@ -1115,20 +1711,27 @@ class AjfFormsModule {
1115
1711
  }
1116
1712
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1117
1713
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AjfFormsModule, declarations: [AjfAudioFieldComponent,
1714
+ AjfCurrentSlidePipe,
1118
1715
  AjfBarcodeFieldComponent,
1119
1716
  AjfBooleanFieldComponent,
1120
1717
  AjfDateFieldComponent,
1121
1718
  AjfDateInputFieldComponent,
1122
1719
  AjfEmptyFieldComponent,
1720
+ AjfFieldRow,
1123
1721
  AjfFieldWarningDialog,
1124
1722
  AjfFormField,
1723
+ AjfFormIssuesPipe,
1125
1724
  AjfFormRenderer,
1126
1725
  AjfGeolocationFieldComponent,
1127
1726
  AjfInputFieldComponent,
1128
1727
  AjfMultipleChoiceFieldComponent,
1129
1728
  AjfRangeFieldComponent,
1729
+ AjfRepStrip,
1130
1730
  AjfSignatureFieldComponent,
1131
1731
  AjfSingleChoiceFieldComponent,
1732
+ AjfSlideCompletionPipe,
1733
+ AjfSlideHeader,
1734
+ AjfSlideIssuesPipe,
1132
1735
  AjfTableFieldComponent,
1133
1736
  AjfTextFieldComponent,
1134
1737
  AjfTimeFieldComponent,
@@ -1153,6 +1756,7 @@ class AjfFormsModule {
1153
1756
  MatFormFieldModule,
1154
1757
  MatIconModule,
1155
1758
  MatInputModule,
1759
+ MatMenuModule,
1156
1760
  MatNativeDateModule,
1157
1761
  MatRadioModule,
1158
1762
  MatSelectModule,
@@ -1162,7 +1766,7 @@ class AjfFormsModule {
1162
1766
  ReactiveFormsModule,
1163
1767
  TextFieldModule,
1164
1768
  MatSliderModule,
1165
- NgxMatSelectSearchModule, i4$3.QuillModule], exports: [AjfFormField, AjfFormRenderer] }); }
1769
+ NgxMatSelectSearchModule, i4$3.QuillModule], exports: [AjfFieldRow, AjfFormField, AjfFormRenderer, AjfRepStrip, AjfSlideHeader] }); }
1166
1770
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AjfFormsModule, providers: [
1167
1771
  AjfFieldService,
1168
1772
  { provide: AJF_WARNING_ALERT_SERVICE, useClass: AjfWarningAlertService },
@@ -1186,6 +1790,7 @@ class AjfFormsModule {
1186
1790
  MatFormFieldModule,
1187
1791
  MatIconModule,
1188
1792
  MatInputModule,
1793
+ MatMenuModule,
1189
1794
  MatNativeDateModule,
1190
1795
  MatRadioModule,
1191
1796
  MatSelectModule,
@@ -1222,6 +1827,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1222
1827
  MatFormFieldModule,
1223
1828
  MatIconModule,
1224
1829
  MatInputModule,
1830
+ MatMenuModule,
1225
1831
  MatNativeDateModule,
1226
1832
  MatRadioModule,
1227
1833
  MatSelectModule,
@@ -1236,27 +1842,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1236
1842
  ],
1237
1843
  declarations: [
1238
1844
  AjfAudioFieldComponent,
1845
+ AjfCurrentSlidePipe,
1239
1846
  AjfBarcodeFieldComponent,
1240
1847
  AjfBooleanFieldComponent,
1241
1848
  AjfDateFieldComponent,
1242
1849
  AjfDateInputFieldComponent,
1243
1850
  AjfEmptyFieldComponent,
1851
+ AjfFieldRow,
1244
1852
  AjfFieldWarningDialog,
1245
1853
  AjfFormField,
1854
+ AjfFormIssuesPipe,
1246
1855
  AjfFormRenderer,
1247
1856
  AjfGeolocationFieldComponent,
1248
1857
  AjfInputFieldComponent,
1249
1858
  AjfMultipleChoiceFieldComponent,
1250
1859
  AjfRangeFieldComponent,
1860
+ AjfRepStrip,
1251
1861
  AjfSignatureFieldComponent,
1252
1862
  AjfSingleChoiceFieldComponent,
1863
+ AjfSlideCompletionPipe,
1864
+ AjfSlideHeader,
1865
+ AjfSlideIssuesPipe,
1253
1866
  AjfTableFieldComponent,
1254
1867
  AjfTextFieldComponent,
1255
1868
  AjfTimeFieldComponent,
1256
1869
  AjfVideoUrlFieldComponent,
1257
1870
  AjfDisplayFieldComponent,
1258
1871
  ],
1259
- exports: [AjfFormField, AjfFormRenderer],
1872
+ exports: [AjfFieldRow, AjfFormField, AjfFormRenderer, AjfRepStrip, AjfSlideHeader],
1260
1873
  providers: [
1261
1874
  AjfFieldService,
1262
1875
  { provide: AJF_WARNING_ALERT_SERVICE, useClass: AjfWarningAlertService },
@@ -1290,5 +1903,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1290
1903
  * Generated bundle index. Do not edit.
1291
1904
  */
1292
1905
 
1293
- export { AjfBooleanFieldComponent, AjfDateFieldComponent, AjfDateInputFieldComponent, AjfEmptyFieldComponent, AjfFieldService, AjfFieldWarningDialog, AjfFormField, AjfFormRenderer, AjfFormsModule, AjfInputFieldComponent, AjfMultipleChoiceFieldComponent, AjfSingleChoiceFieldComponent, AjfTableFieldComponent, AjfTimeFieldComponent, AjfWarningAlertService };
1906
+ export { AjfBooleanFieldComponent, AjfCurrentSlidePipe, AjfDateFieldComponent, AjfDateInputFieldComponent, AjfEmptyFieldComponent, AjfFieldRow, AjfFieldService, AjfFieldWarningDialog, AjfFormField, AjfFormIssuesPipe, AjfFormRenderer, AjfFormsModule, AjfInputFieldComponent, AjfMultipleChoiceFieldComponent, AjfRepStrip, AjfSingleChoiceFieldComponent, AjfSlideCompletionPipe, AjfSlideHeader, AjfSlideIssuesPipe, AjfTableFieldComponent, AjfTimeFieldComponent, AjfWarningAlertService };
1294
1907
  //# sourceMappingURL=ajf-material-forms.mjs.map