@tft/crispr-forms 21.0.6 → 21.0.7

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 (45) hide show
  1. package/fesm2022/{tft-crispr-forms-autocomplete-field.component-BrFPYj9i.mjs → tft-crispr-forms-autocomplete-field.component-5AUQpu-H.mjs} +3 -3
  2. package/fesm2022/{tft-crispr-forms-autocomplete-field.component-BrFPYj9i.mjs.map → tft-crispr-forms-autocomplete-field.component-5AUQpu-H.mjs.map} +1 -1
  3. package/fesm2022/{tft-crispr-forms-index-1oUkFYPd.mjs → tft-crispr-forms-index-8P67IPdA.mjs} +2 -2
  4. package/fesm2022/{tft-crispr-forms-index-1oUkFYPd.mjs.map → tft-crispr-forms-index-8P67IPdA.mjs.map} +1 -1
  5. package/fesm2022/tft-crispr-forms-index-BLUFuqw1.mjs +2 -0
  6. package/fesm2022/tft-crispr-forms-index-BLUFuqw1.mjs.map +1 -0
  7. package/fesm2022/{tft-crispr-forms-index-BVUDqeAd.mjs → tft-crispr-forms-index-Bdw8TYUH.mjs} +3 -3
  8. package/fesm2022/{tft-crispr-forms-index-BVUDqeAd.mjs.map → tft-crispr-forms-index-Bdw8TYUH.mjs.map} +1 -1
  9. package/fesm2022/{tft-crispr-forms-index-B9tVg0fe.mjs → tft-crispr-forms-index-C1iXzOLu.mjs} +2 -2
  10. package/fesm2022/{tft-crispr-forms-index-B9tVg0fe.mjs.map → tft-crispr-forms-index-C1iXzOLu.mjs.map} +1 -1
  11. package/fesm2022/{tft-crispr-forms-index-CLSsoEGa.mjs → tft-crispr-forms-index-C7a9kPiI.mjs} +2 -2
  12. package/fesm2022/{tft-crispr-forms-index-CLSsoEGa.mjs.map → tft-crispr-forms-index-C7a9kPiI.mjs.map} +1 -1
  13. package/fesm2022/{tft-crispr-forms-index-hpO3y8-r.mjs → tft-crispr-forms-index-CNj1hHu0.mjs} +2 -2
  14. package/fesm2022/{tft-crispr-forms-index-hpO3y8-r.mjs.map → tft-crispr-forms-index-CNj1hHu0.mjs.map} +1 -1
  15. package/fesm2022/{tft-crispr-forms-index-Cch_yKzh.mjs → tft-crispr-forms-index-D3A-_fjt.mjs} +3 -3
  16. package/fesm2022/{tft-crispr-forms-index-Cch_yKzh.mjs.map → tft-crispr-forms-index-D3A-_fjt.mjs.map} +1 -1
  17. package/fesm2022/{tft-crispr-forms-index-By2zsul9.mjs → tft-crispr-forms-index-D5lBB-Ij.mjs} +2 -2
  18. package/fesm2022/{tft-crispr-forms-index-By2zsul9.mjs.map → tft-crispr-forms-index-D5lBB-Ij.mjs.map} +1 -1
  19. package/fesm2022/tft-crispr-forms-index-Ds-aTtVF.mjs +54 -0
  20. package/fesm2022/tft-crispr-forms-index-Ds-aTtVF.mjs.map +1 -0
  21. package/fesm2022/{tft-crispr-forms-index-SXLsJ2dx.mjs → tft-crispr-forms-index-Re8QtaY6.mjs} +2 -2
  22. package/fesm2022/{tft-crispr-forms-index-SXLsJ2dx.mjs.map → tft-crispr-forms-index-Re8QtaY6.mjs.map} +1 -1
  23. package/fesm2022/{tft-crispr-forms-index-BYfudl7n.mjs → tft-crispr-forms-index-bPD4OWet.mjs} +5 -7
  24. package/fesm2022/tft-crispr-forms-index-bPD4OWet.mjs.map +1 -0
  25. package/fesm2022/tft-crispr-forms-index-dzKPRt9Z.mjs +18 -0
  26. package/fesm2022/tft-crispr-forms-index-dzKPRt9Z.mjs.map +1 -0
  27. package/fesm2022/{tft-crispr-forms-index-BNGj_Q31.mjs → tft-crispr-forms-index-e4zApZth.mjs} +3 -3
  28. package/fesm2022/{tft-crispr-forms-index-BNGj_Q31.mjs.map → tft-crispr-forms-index-e4zApZth.mjs.map} +1 -1
  29. package/fesm2022/{tft-crispr-forms-index-CMJfbPJv.mjs → tft-crispr-forms-index-sSHOh9Ed.mjs} +2 -2
  30. package/fesm2022/{tft-crispr-forms-index-CMJfbPJv.mjs.map → tft-crispr-forms-index-sSHOh9Ed.mjs.map} +1 -1
  31. package/fesm2022/{tft-crispr-forms-index-HtH17liK.mjs → tft-crispr-forms-index-xlzLH5Sr.mjs} +3 -3
  32. package/fesm2022/{tft-crispr-forms-index-HtH17liK.mjs.map → tft-crispr-forms-index-xlzLH5Sr.mjs.map} +1 -1
  33. package/fesm2022/{tft-crispr-forms-tft-crispr-forms-Dhjn_QdV.mjs → tft-crispr-forms-tft-crispr-forms-D-kHHD0p.mjs} +151 -222
  34. package/fesm2022/tft-crispr-forms-tft-crispr-forms-D-kHHD0p.mjs.map +1 -0
  35. package/fesm2022/tft-crispr-forms.mjs +1 -1
  36. package/package.json +1 -1
  37. package/types/tft-crispr-forms.d.ts +61 -66
  38. package/fesm2022/tft-crispr-forms-index-BYfudl7n.mjs.map +0 -1
  39. package/fesm2022/tft-crispr-forms-index-CXHhQct3.mjs +0 -2
  40. package/fesm2022/tft-crispr-forms-index-CXHhQct3.mjs.map +0 -1
  41. package/fesm2022/tft-crispr-forms-index-SEXABbga.mjs +0 -17
  42. package/fesm2022/tft-crispr-forms-index-SEXABbga.mjs.map +0 -1
  43. package/fesm2022/tft-crispr-forms-index-g-9P16CE.mjs +0 -61
  44. package/fesm2022/tft-crispr-forms-index-g-9P16CE.mjs.map +0 -1
  45. package/fesm2022/tft-crispr-forms-tft-crispr-forms-Dhjn_QdV.mjs.map +0 -1
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, input, computed, Input, Directive, inject, DestroyRef, EventEmitter, effect, Output, ViewContainerRef, Renderer2, ChangeDetectorRef, Pipe, NgModule, ViewChild, Component, HostListener, ChangeDetectionStrategy } from '@angular/core';
2
+ import { input, computed, Directive, inject, DestroyRef, EventEmitter, effect, Output, ViewContainerRef, Renderer2, Pipe, NgModule, output, untracked, ViewChild, ChangeDetectionStrategy, Component, HostListener, Input, signal } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1$1 from '@angular/forms';
6
6
  import { FormArray, FormControl, FormGroup, ReactiveFormsModule, NgControl } from '@angular/forms';
7
7
  import * as i6 from '@tft/form-validation-handler';
8
8
  import { FormValidationHandlerModule } from '@tft/form-validation-handler';
9
- import { from, of, isObservable } from 'rxjs';
9
+ import { takeUntilDestroyed, outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
10
10
  import { map, startWith, debounceTime, distinctUntilChanged, switchMap, shareReplay, tap } from 'rxjs/operators';
11
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
+ import { from, of, isObservable } from 'rxjs';
12
12
  import * as i1$3 from '@angular/material/button';
13
13
  import { MatButtonModule } from '@angular/material/button';
14
14
  import * as i2 from '@angular/material/icon';
@@ -213,7 +213,11 @@ function allowedFileType(matchExp) {
213
213
 
214
214
  class CrisprFieldComponent {
215
215
  constructor() {
216
- this.config = signal(null, ...(ngDevMode ? [{ debugName: "config" }] : []));
216
+ this.inputConfig = input(null, { ...(ngDevMode ? { debugName: "inputConfig" } : {}), alias: 'config' });
217
+ this.config = computed(() => {
218
+ const c = this.inputConfig();
219
+ return c && this.defaultConfig ? { ...this.defaultConfig, ...c } : c;
220
+ }, ...(ngDevMode ? [{ debugName: "config" }] : []));
217
221
  this.testIdPrefix = input(undefined, ...(ngDevMode ? [{ debugName: "testIdPrefix" }] : []));
218
222
  this.testId = computed(() => {
219
223
  const controlName = this.config()?.controlName;
@@ -223,46 +227,24 @@ class CrisprFieldComponent {
223
227
  return prefix ? `${prefix}.${controlName}` : controlName;
224
228
  }, ...(ngDevMode ? [{ debugName: "testId" }] : []));
225
229
  }
226
- // eslint-disable-next-line @angular-eslint/no-input-rename
227
- set inputConfig(config) {
228
- this.updateConfig(config);
229
- }
230
- updateConfig(inputConfig) {
231
- const mergedConfig = this.defaultConfig ? { ...this.defaultConfig, ...inputConfig } : inputConfig;
232
- this.config.set(mergedConfig);
233
- }
234
230
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
235
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.6", type: CrisprFieldComponent, isStandalone: true, inputs: { inputConfig: { classPropertyName: "inputConfig", publicName: "config", isSignal: false, isRequired: false, transformFunction: null }, testIdPrefix: { classPropertyName: "testIdPrefix", publicName: "testIdPrefix", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
231
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.6", type: CrisprFieldComponent, isStandalone: true, inputs: { inputConfig: { classPropertyName: "inputConfig", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, testIdPrefix: { classPropertyName: "testIdPrefix", publicName: "testIdPrefix", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
236
232
  }
237
233
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldComponent, decorators: [{
238
234
  type: Directive,
239
235
  args: [{
240
236
  standalone: true
241
237
  }]
242
- }], propDecorators: { inputConfig: [{
243
- type: Input,
244
- args: [{ alias: 'config' }]
245
- }], testIdPrefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "testIdPrefix", required: false }] }] } });
238
+ }], propDecorators: { inputConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], testIdPrefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "testIdPrefix", required: false }] }] } });
246
239
 
247
240
  class CrisprControlComponent extends CrisprFieldComponent {
248
- // eslint-disable-next-line @angular-eslint/no-input-rename
249
- set inputGroup(group) {
250
- this.group.set(group);
251
- }
252
- /*
253
- * Having the input alias allows us to consume these components in the traditional Angular way as well as progammatically in the form builder
254
- */
255
- // eslint-disable-next-line @angular-eslint/no-input-rename
256
- set inputValue(value) {
257
- this.value.set(value);
258
- }
259
241
  constructor() {
260
242
  super();
261
243
  this.destroyRef = inject(DestroyRef);
262
- this.group = signal(null, ...(ngDevMode ? [{ debugName: "group" }] : []));
244
+ this.group = input(null, ...(ngDevMode ? [{ debugName: "group" }] : []));
263
245
  this.control = computed(() => this.group()?.get(this.config().controlName), ...(ngDevMode ? [{ debugName: "control" }] : []));
264
246
  this.valueChanges = new EventEmitter();
265
- this.value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
247
+ this.value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
266
248
  effect(() => {
267
249
  this.setControlValue(this.value());
268
250
  });
@@ -282,22 +264,16 @@ class CrisprControlComponent extends CrisprFieldComponent {
282
264
  }
283
265
  }
284
266
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
285
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.6", type: CrisprControlComponent, isStandalone: true, inputs: { inputGroup: ["group", "inputGroup"], inputValue: ["value", "inputValue"] }, outputs: { valueChanges: "valueChanges" }, usesInheritance: true, ngImport: i0 }); }
267
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.6", type: CrisprControlComponent, isStandalone: true, inputs: { group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChanges: "valueChanges" }, usesInheritance: true, ngImport: i0 }); }
286
268
  }
287
269
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprControlComponent, decorators: [{
288
270
  type: Directive,
289
271
  args: [{
290
272
  standalone: true
291
273
  }]
292
- }], ctorParameters: () => [], propDecorators: { inputGroup: [{
293
- type: Input,
294
- args: [{ alias: 'group' }]
295
- }], valueChanges: [{
274
+ }], ctorParameters: () => [], propDecorators: { group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], valueChanges: [{
296
275
  type: Output
297
- }], inputValue: [{
298
- type: Input,
299
- args: [{ alias: 'value' }]
300
- }] } });
276
+ }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
301
277
 
302
278
  // eslint-disable-next-line @angular-eslint/directive-class-suffix
303
279
  class AbstractAutocompleteComponent extends CrisprControlComponent {
@@ -305,7 +281,8 @@ class AbstractAutocompleteComponent extends CrisprControlComponent {
305
281
  super(...arguments);
306
282
  // we need a separate control for the UI because of the way the material autocomplete chiplist works
307
283
  this.autocompleteInputControl = new FormControl('');
308
- this.config = signal(null, ...(ngDevMode ? [{ debugName: "config" }] : []));
284
+ // Narrows the parent's computed config type to include C-specific properties (e.g. chiplist-only fields)
285
+ this.config = computed(() => this.inputConfig(), ...(ngDevMode ? [{ debugName: "config" }] : []));
309
286
  }
310
287
  ngOnInit() {
311
288
  super.ngOnInit();
@@ -334,22 +311,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
334
311
  const FIELD_COMPONENTS = {
335
312
  groupList: () => Promise.resolve().then(function () { return index$1; }).then(({ FormGroupListComponent }) => FormGroupListComponent),
336
313
  subGroup: () => Promise.resolve().then(function () { return index; }).then(({ SubGroupComponent }) => SubGroupComponent),
337
- button: () => import('./tft-crispr-forms-index-g-9P16CE.mjs').then(({ ButtonComponent }) => ButtonComponent),
338
- input: () => import('./tft-crispr-forms-index-CLSsoEGa.mjs').then(({ InputFieldComponent }) => InputFieldComponent),
339
- select: () => import('./tft-crispr-forms-index-BNGj_Q31.mjs').then(({ SelectFieldComponent }) => SelectFieldComponent),
340
- radio: () => import('./tft-crispr-forms-index-hpO3y8-r.mjs').then(({ RadioFieldComponent }) => RadioFieldComponent),
341
- autocomplete: () => import('./tft-crispr-forms-index-CXHhQct3.mjs').then(({ AutocompleteFieldComponent }) => AutocompleteFieldComponent),
342
- autocompleteChiplist: () => import('./tft-crispr-forms-index-Cch_yKzh.mjs').then(({ AutocompleteChiplistFieldComponent }) => AutocompleteChiplistFieldComponent),
343
- map: () => import('./tft-crispr-forms-index-BVUDqeAd.mjs').then(({ MapFieldComponent }) => MapFieldComponent),
344
- textarea: () => import('./tft-crispr-forms-index-B9tVg0fe.mjs').then(({ TextareaFieldComponent }) => TextareaFieldComponent),
345
- checkbox: () => import('./tft-crispr-forms-index-SXLsJ2dx.mjs').then(({ CheckboxFieldComponent }) => CheckboxFieldComponent),
346
- slider: () => import('./tft-crispr-forms-index-By2zsul9.mjs').then(({ SliderFieldComponent }) => SliderFieldComponent),
347
- datepicker: () => import('./tft-crispr-forms-index-1oUkFYPd.mjs').then(({ DatepickerFieldComponent }) => DatepickerFieldComponent),
314
+ button: () => import('./tft-crispr-forms-index-Ds-aTtVF.mjs').then(({ ButtonComponent }) => ButtonComponent),
315
+ input: () => import('./tft-crispr-forms-index-C7a9kPiI.mjs').then(({ InputFieldComponent }) => InputFieldComponent),
316
+ select: () => import('./tft-crispr-forms-index-e4zApZth.mjs').then(({ SelectFieldComponent }) => SelectFieldComponent),
317
+ radio: () => import('./tft-crispr-forms-index-CNj1hHu0.mjs').then(({ RadioFieldComponent }) => RadioFieldComponent),
318
+ autocomplete: () => import('./tft-crispr-forms-index-BLUFuqw1.mjs').then(({ AutocompleteFieldComponent }) => AutocompleteFieldComponent),
319
+ autocompleteChiplist: () => import('./tft-crispr-forms-index-D3A-_fjt.mjs').then(({ AutocompleteChiplistFieldComponent }) => AutocompleteChiplistFieldComponent),
320
+ map: () => import('./tft-crispr-forms-index-Bdw8TYUH.mjs').then(({ MapFieldComponent }) => MapFieldComponent),
321
+ textarea: () => import('./tft-crispr-forms-index-C1iXzOLu.mjs').then(({ TextareaFieldComponent }) => TextareaFieldComponent),
322
+ checkbox: () => import('./tft-crispr-forms-index-Re8QtaY6.mjs').then(({ CheckboxFieldComponent }) => CheckboxFieldComponent),
323
+ slider: () => import('./tft-crispr-forms-index-D5lBB-Ij.mjs').then(({ SliderFieldComponent }) => SliderFieldComponent),
324
+ datepicker: () => import('./tft-crispr-forms-index-8P67IPdA.mjs').then(({ DatepickerFieldComponent }) => DatepickerFieldComponent),
348
325
  fileUpload: () => Promise.resolve().then(function () { return index$3; }).then(({ FileUploadFieldComponent }) => FileUploadFieldComponent),
349
- imageUpload: () => import('./tft-crispr-forms-index-BYfudl7n.mjs').then(({ ImageUploadFieldComponent }) => ImageUploadFieldComponent),
326
+ imageUpload: () => import('./tft-crispr-forms-index-bPD4OWet.mjs').then(({ ImageUploadFieldComponent }) => ImageUploadFieldComponent),
350
327
  heading: () => Promise.resolve().then(function () { return index$2; }).then(({ HeadingComponent }) => HeadingComponent),
351
- divider: () => import('./tft-crispr-forms-index-CMJfbPJv.mjs').then(({ DividerComponent }) => DividerComponent),
352
- unitConversion: () => import('./tft-crispr-forms-index-HtH17liK.mjs').then(({ UnitConversionFieldComponent }) => UnitConversionFieldComponent),
328
+ divider: () => import('./tft-crispr-forms-index-sSHOh9Ed.mjs').then(({ DividerComponent }) => DividerComponent),
329
+ unitConversion: () => import('./tft-crispr-forms-index-xlzLH5Sr.mjs').then(({ UnitConversionFieldComponent }) => UnitConversionFieldComponent),
353
330
  };
354
331
  function isControlComponent(component) {
355
332
  return component && isControlConfig(component.config()) && 'value' in component;
@@ -361,55 +338,46 @@ function isControlOrButtonComponent(component) {
361
338
 
362
339
  class CrisprFieldDirective {
363
340
  constructor() {
341
+ this.config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : []));
342
+ this.group = input(...(ngDevMode ? [undefined, { debugName: "group" }] : []));
343
+ this.testIdPrefix = input(undefined, ...(ngDevMode ? [{ debugName: "testIdPrefix" }] : []));
344
+ this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
364
345
  this.container = inject(ViewContainerRef);
365
346
  this.renderer = inject(Renderer2);
366
- this.cdr = inject(ChangeDetectorRef);
367
- }
368
- set value(value) {
369
- this._value = value;
370
- // This is needed to keep the group list from resetting control values to the initial input value
371
- this.updateComponentValue(value);
372
- }
373
- get value() {
374
- return this._value;
347
+ effect(() => {
348
+ this.updateComponentValue(this.value());
349
+ });
375
350
  }
376
351
  async ngOnInit() {
377
- /**
378
- * create component and set values from config on its instance
379
- */
380
- const component = this.config.component ||
381
- (await FIELD_COMPONENTS[this.config.controlType]());
382
- const componentRef = this.container.createComponent(component);
383
- this.component = componentRef.instance;
384
- componentRef.setInput('config', this.config);
352
+ const component = this.config().component ||
353
+ (await FIELD_COMPONENTS[this.config().controlType]());
354
+ this.componentRef =
355
+ this.container.createComponent(component);
356
+ this.component = this.componentRef.instance;
357
+ this.componentRef.setInput('config', this.config());
385
358
  if (isControlOrButtonComponent(this.component)) {
386
- componentRef.setInput('group', this.group);
359
+ this.componentRef.setInput('group', this.group());
387
360
  }
388
- componentRef.setInput('testIdPrefix', this.testIdPrefix);
389
- this.updateComponentValue(this.value);
390
- // adds any config classes to the dynamically generated component
391
- // doing this here keeps us from having to extend a base component into each field component individually
392
- if (!this.config.classes)
361
+ this.componentRef.setInput('testIdPrefix', this.testIdPrefix());
362
+ this.updateComponentValue(this.value());
363
+ if (!this.config().classes)
393
364
  return;
394
- this.config.classes.forEach((klass) => {
395
- // check for passing multiple classes in one array element
365
+ this.config().classes.forEach((klass) => {
396
366
  if (klass.includes(' ')) {
397
367
  throw Error(`Improperly formatted class. '${klass}' cannot contain spaces.`);
398
368
  }
399
369
  else {
400
- this.renderer.addClass(componentRef.location.nativeElement, klass);
370
+ this.renderer.addClass(this.componentRef.location.nativeElement, klass);
401
371
  }
402
372
  });
403
373
  }
404
374
  updateComponentValue(value) {
405
- if (isControlComponent(this.component)) {
406
- this.component.value.set(value);
407
- // SubGroups won't populate without this detectChanges
408
- this.cdr.detectChanges();
375
+ if (this.componentRef && isControlComponent(this.component)) {
376
+ this.componentRef.setInput('value', value);
409
377
  }
410
378
  }
411
379
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
412
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.6", type: CrisprFieldDirective, isStandalone: true, selector: "[crisprField]", inputs: { config: "config", group: "group", testIdPrefix: "testIdPrefix", value: "value" }, ngImport: i0 }); }
380
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.6", type: CrisprFieldDirective, isStandalone: true, selector: "[crisprField]", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, testIdPrefix: { classPropertyName: "testIdPrefix", publicName: "testIdPrefix", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
413
381
  }
414
382
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldDirective, decorators: [{
415
383
  type: Directive,
@@ -417,15 +385,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
417
385
  selector: '[crisprField]',
418
386
  standalone: true,
419
387
  }]
420
- }], propDecorators: { config: [{
421
- type: Input
422
- }], group: [{
423
- type: Input
424
- }], testIdPrefix: [{
425
- type: Input
426
- }], value: [{
427
- type: Input
428
- }] } });
388
+ }], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], testIdPrefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "testIdPrefix", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
429
389
 
430
390
  class InitialControlValuePipe {
431
391
  // TODO: does changing any to unknown break anything?
@@ -467,49 +427,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
467
427
 
468
428
  class CrisprFormComponent {
469
429
  constructor() {
470
- this.form = new FormGroup({});
471
- this.value = null;
472
- this.submitted = new EventEmitter();
430
+ this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
431
+ this.form = input(new FormGroup({}), ...(ngDevMode ? [{ debugName: "form" }] : []));
432
+ this.value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
433
+ this.submitted = output();
434
+ /** Patch form values whenever the [value] input changes without firing valueChanges. */
435
+ this.patchValueEffect = effect(() => {
436
+ const value = this.value();
437
+ untracked(() => {
438
+ if (value) {
439
+ this.form().patchValue(value, { emitEvent: false });
440
+ }
441
+ });
442
+ }, ...(ngDevMode ? [{ debugName: "patchValueEffect" }] : []));
473
443
  // proxy value and status change events through to consuming component
474
- this.valueChanges = this.form.valueChanges;
475
- this.statusChanges = this.form.statusChanges;
444
+ this.valueChanges = outputFromObservable(toObservable(this.form).pipe(switchMap((f) => f.valueChanges)));
445
+ this.statusChanges = outputFromObservable(toObservable(this.form).pipe(switchMap((f) => f.statusChanges)));
476
446
  }
477
447
  ngOnInit() {
478
448
  // build out the form, note that we pass in the form as the third argument and the function modifies it
479
- buildFormGroupFromConfig(this.config, this.value, this.form);
449
+ buildFormGroupFromConfig(this.config(), this.value(), this.form());
480
450
  }
481
451
  handleSubmit() {
482
- this.form.markAllAsTouched();
483
- this.submitted.emit(this.form);
452
+ this.form().markAllAsTouched();
453
+ this.submitted.emit(this.form());
484
454
  }
485
455
  triggerSubmit() {
486
456
  this.submitTrigger.nativeElement.click();
487
457
  }
488
458
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
489
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: CrisprFormComponent, isStandalone: true, selector: "crispr-form", inputs: { config: "config", form: "form", value: "value" }, outputs: { submitted: "submitted", valueChanges: "valueChanges", statusChanges: "statusChanges" }, viewQueries: [{ propertyName: "submitTrigger", first: true, predicate: ["submitTrigger"], descendants: true }], ngImport: i0, template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config.classes\"\n [formGroup]=\"form\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config.autocomplete || 'off'\"\n [errorDictionary]=\"config.errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n @for (field of config.fields; track field) {\n <ng-container\n crisprField\n [value]=\"value | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form\">\n </ng-container>\n }\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" data-testid=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "testIdPrefix", "value"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormValidationHandlerModule }, { kind: "directive", type: i6.ControlErrorsFormDirective, selector: "form", inputs: ["errorDictionary"] }, { kind: "directive", type: i6.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { kind: "ngmodule", type: CrisprPipesModule }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }], preserveWhitespaces: true }); }
459
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: CrisprFormComponent, isStandalone: true, selector: "crispr-form", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted", valueChanges: "valueChanges", statusChanges: "statusChanges" }, viewQueries: [{ propertyName: "submitTrigger", first: true, predicate: ["submitTrigger"], descendants: true }], ngImport: i0, template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config().classes\"\n [formGroup]=\"form()\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config().autocomplete || 'off'\"\n [errorDictionary]=\"config().errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n @for (field of config().fields; track field) {\n <ng-container\n crisprField\n [value]=\"value() | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form()\">\n </ng-container>\n }\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" data-testid=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "testIdPrefix", "value"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormValidationHandlerModule }, { kind: "directive", type: i6.ControlErrorsFormDirective, selector: "form", inputs: ["errorDictionary"] }, { kind: "directive", type: i6.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { kind: "ngmodule", type: CrisprPipesModule }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
490
460
  }
491
461
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormComponent, decorators: [{
492
462
  type: Component,
493
- args: [{ selector: 'crispr-form', imports: [
463
+ args: [{ selector: 'crispr-form', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
494
464
  CommonModule,
495
465
  CrisprFieldDirective,
496
466
  ReactiveFormsModule,
497
467
  FormValidationHandlerModule,
498
468
  CrisprPipesModule,
499
- ], template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config.classes\"\n [formGroup]=\"form\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config.autocomplete || 'off'\"\n [errorDictionary]=\"config.errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n @for (field of config.fields; track field) {\n <ng-container\n crisprField\n [value]=\"value | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form\">\n </ng-container>\n }\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" data-testid=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"] }]
500
- }], propDecorators: { config: [{
501
- type: Input
502
- }], form: [{
503
- type: Input
504
- }], value: [{
505
- type: Input
506
- }], submitted: [{
507
- type: Output
508
- }], valueChanges: [{
509
- type: Output
510
- }], statusChanges: [{
511
- type: Output
512
- }], submitTrigger: [{
469
+ ], template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config().classes\"\n [formGroup]=\"form()\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config().autocomplete || 'off'\"\n [errorDictionary]=\"config().errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n @for (field of config().fields; track field) {\n <ng-container\n crisprField\n [value]=\"value() | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form()\">\n </ng-container>\n }\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" data-testid=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"] }]
470
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], submitted: [{ type: i0.Output, args: ["submitted"] }], valueChanges: [{ type: i0.Output, args: ["valueChanges"] }], statusChanges: [{ type: i0.Output, args: ["statusChanges"] }], submitTrigger: [{
513
471
  type: ViewChild,
514
472
  args: ['submitTrigger']
515
473
  }] } });
@@ -553,18 +511,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
553
511
  }] } });
554
512
 
555
513
  class InfoComponent {
514
+ constructor() {
515
+ this.info = input.required(...(ngDevMode ? [{ debugName: "info" }] : []));
516
+ }
556
517
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: InfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
557
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: InfoComponent, isStandalone: true, selector: "crispr-info", inputs: { info: "info" }, ngImport: i0, template: "@if (info) {\n <mat-icon\n [matTooltip]=\"info.content\"\n [matTooltipPosition]=\"info.tooltipPosition || 'below'\">\n {{info.iconName || 'info'}}\n </mat-icon>\n}\n", styles: [":host{margin-left:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
518
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: InfoComponent, isStandalone: true, selector: "crispr-info", inputs: { info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@if (info()) {\n <mat-icon\n [matTooltip]=\"info().content\"\n [matTooltipPosition]=\"info().tooltipPosition || 'below'\">\n {{info().iconName || 'info'}}\n </mat-icon>\n}\n", styles: [":host{margin-left:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
558
519
  }
559
520
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: InfoComponent, decorators: [{
560
521
  type: Component,
561
- args: [{ selector: 'crispr-info', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
522
+ args: [{ selector: 'crispr-info', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
562
523
  MatIconModule,
563
524
  MatTooltipModule
564
- ], template: "@if (info) {\n <mat-icon\n [matTooltip]=\"info.content\"\n [matTooltipPosition]=\"info.tooltipPosition || 'below'\">\n {{info.iconName || 'info'}}\n </mat-icon>\n}\n", styles: [":host{margin-left:4px}\n"] }]
565
- }], propDecorators: { info: [{
566
- type: Input
567
- }] } });
525
+ ], template: "@if (info()) {\n <mat-icon\n [matTooltip]=\"info().content\"\n [matTooltipPosition]=\"info().tooltipPosition || 'below'\">\n {{info().iconName || 'info'}}\n </mat-icon>\n}\n", styles: [":host{margin-left:4px}\n"] }]
526
+ }], propDecorators: { info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: true }] }] } });
568
527
 
569
528
  const defaultConfig$1 = {
570
529
  typographyClass: 'mat-h3',
@@ -584,17 +543,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
584
543
 
585
544
  class FieldContainerComponent {
586
545
  constructor() {
546
+ // the configuration object for the field
547
+ this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
548
+ // the parent formGroup
549
+ this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
587
550
  // boolean whether field-container is inline
588
- this.inlineField = false;
551
+ this.inlineField = input(false, ...(ngDevMode ? [{ debugName: "inlineField" }] : []));
589
552
  this.subs = [];
590
553
  }
591
554
  ngOnInit() {
592
- this.disabled$ = this.connectDisabledCallback(this.group, this.config);
555
+ this.disabled$ = this.connectDisabledCallback(this.group(), this.config());
593
556
  // we tried moving this into afterViewChecked and afterContentChecked lifecycle hooks without any luck
594
- if (this.config.computeValue) {
595
- this.subs.push(this.config
596
- .computeValue(this.group)
597
- .pipe(distinctUntilChanged(), tap((computedValue) => this.group.get(this.config.controlName).setValue(computedValue)))
557
+ if (this.config().computeValue) {
558
+ this.subs.push(this.config()
559
+ .computeValue(this.group())
560
+ .pipe(distinctUntilChanged(), tap((computedValue) => this.group().get(this.config().controlName).setValue(computedValue)))
598
561
  .subscribe());
599
562
  }
600
563
  }
@@ -620,37 +583,29 @@ class FieldContainerComponent {
620
583
  : of(false);
621
584
  }
622
585
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FieldContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
623
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: FieldContainerComponent, isStandalone: true, selector: "crispr-field-container", inputs: { config: "config", group: "group", inlineField: "inlineField" }, ngImport: i0, template: "@if ((disabled$ | async) ? !config.hideDisabled : true) {\n <div\n [ngClass]=\"config.classes\"\n [class.inline-field]=\"inlineField\"\n class=\"field-container\">\n @if (config.heading) {\n <crispr-heading\n [config]=\"config.heading\">\n </crispr-heading>\n }\n <ng-content>\n </ng-content>\n </div>\n}\n", styles: ["::ng-deep mat-form-field.mat-mdc-form-field{display:block;padding:.25em 0}.inline-field{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeadingComponent, selector: "crispr-heading" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
586
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: FieldContainerComponent, isStandalone: true, selector: "crispr-field-container", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null }, inlineField: { classPropertyName: "inlineField", publicName: "inlineField", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if ((disabled$ | async) ? !config().hideDisabled : true) {\n <div\n [ngClass]=\"config().classes\"\n [class.inline-field]=\"inlineField()\"\n class=\"field-container\">\n @if (config().heading) {\n <crispr-heading\n [config]=\"config().heading\">\n </crispr-heading>\n }\n <ng-content>\n </ng-content>\n </div>\n}\n", styles: ["::ng-deep mat-form-field.mat-mdc-form-field{display:block;padding:.25em 0}.inline-field{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeadingComponent, selector: "crispr-heading" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
624
587
  }
625
588
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FieldContainerComponent, decorators: [{
626
589
  type: Component,
627
- args: [{ selector: 'crispr-field-container', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, HeadingComponent], template: "@if ((disabled$ | async) ? !config.hideDisabled : true) {\n <div\n [ngClass]=\"config.classes\"\n [class.inline-field]=\"inlineField\"\n class=\"field-container\">\n @if (config.heading) {\n <crispr-heading\n [config]=\"config.heading\">\n </crispr-heading>\n }\n <ng-content>\n </ng-content>\n </div>\n}\n", styles: ["::ng-deep mat-form-field.mat-mdc-form-field{display:block;padding:.25em 0}.inline-field{display:inline-block}\n"] }]
628
- }], propDecorators: { config: [{
629
- type: Input
630
- }], group: [{
631
- type: Input
632
- }], inlineField: [{
633
- type: Input
634
- }] } });
590
+ args: [{ selector: 'crispr-field-container', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, HeadingComponent], template: "@if ((disabled$ | async) ? !config().hideDisabled : true) {\n <div\n [ngClass]=\"config().classes\"\n [class.inline-field]=\"inlineField()\"\n class=\"field-container\">\n @if (config().heading) {\n <crispr-heading\n [config]=\"config().heading\">\n </crispr-heading>\n }\n <ng-content>\n </ng-content>\n </div>\n}\n", styles: ["::ng-deep mat-form-field.mat-mdc-form-field{display:block;padding:.25em 0}.inline-field{display:inline-block}\n"] }]
591
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: true }] }], inlineField: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineField", required: false }] }] } });
635
592
 
636
593
  class SelectedFileComponent {
594
+ constructor() {
595
+ this.fileName = input.required(...(ngDevMode ? [{ debugName: "fileName" }] : []));
596
+ this.progress = input(...(ngDevMode ? [undefined, { debugName: "progress" }] : []));
597
+ this.showProgress = input(...(ngDevMode ? [undefined, { debugName: "showProgress" }] : []));
598
+ this.color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : []));
599
+ }
637
600
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SelectedFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
638
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SelectedFileComponent, isStandalone: true, selector: "crispr-selected-file", inputs: { fileName: "fileName", progress: "progress", showProgress: "showProgress", color: "color" }, ngImport: i0, template: "<h3 class=\"mat-h3\">{{ fileName }}</h3>\n@if (showProgress) {\n <mat-progress-bar\n mode=\"determinate\"\n [color]=\"color\"\n [value]=\"progress\">\n </mat-progress-bar>\n}\n", styles: ["mat-progress-bar{margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i1$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }], preserveWhitespaces: true }); }
601
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SelectedFileComponent, isStandalone: true, selector: "crispr-selected-file", inputs: { fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: true, transformFunction: null }, progress: { classPropertyName: "progress", publicName: "progress", isSignal: true, isRequired: false, transformFunction: null }, showProgress: { classPropertyName: "showProgress", publicName: "showProgress", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<h3 class=\"mat-h3\">{{ fileName() }}</h3>\n@if (showProgress()) {\n <mat-progress-bar\n mode=\"determinate\"\n [color]=\"color()\"\n [value]=\"progress()\">\n </mat-progress-bar>\n}\n", styles: ["mat-progress-bar{margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i1$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
639
602
  }
640
603
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SelectedFileComponent, decorators: [{
641
604
  type: Component,
642
- args: [{ selector: 'crispr-selected-file', imports: [
605
+ args: [{ selector: 'crispr-selected-file', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
643
606
  MatProgressBarModule
644
- ], template: "<h3 class=\"mat-h3\">{{ fileName }}</h3>\n@if (showProgress) {\n <mat-progress-bar\n mode=\"determinate\"\n [color]=\"color\"\n [value]=\"progress\">\n </mat-progress-bar>\n}\n", styles: ["mat-progress-bar{margin-bottom:8px}\n"] }]
645
- }], propDecorators: { fileName: [{
646
- type: Input
647
- }], progress: [{
648
- type: Input
649
- }], showProgress: [{
650
- type: Input
651
- }], color: [{
652
- type: Input
653
- }] } });
607
+ ], template: "<h3 class=\"mat-h3\">{{ fileName() }}</h3>\n@if (showProgress()) {\n <mat-progress-bar\n mode=\"determinate\"\n [color]=\"color()\"\n [value]=\"progress()\">\n </mat-progress-bar>\n}\n", styles: ["mat-progress-bar{margin-bottom:8px}\n"] }]
608
+ }], propDecorators: { fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: true }] }], progress: [{ type: i0.Input, args: [{ isSignal: true, alias: "progress", required: false }] }], showProgress: [{ type: i0.Input, args: [{ isSignal: true, alias: "showProgress", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
654
609
 
655
610
  /* eslint-disable @nx/enforce-module-boundaries */
656
611
  class FileUploadFieldComponent extends CrisprControlComponent {
@@ -754,35 +709,30 @@ var index$2 = /*#__PURE__*/Object.freeze({
754
709
  class CrisprDisplayFieldDirective {
755
710
  constructor() {
756
711
  this.container = inject(ViewContainerRef);
757
- this.cdr = inject(ChangeDetectorRef);
758
- }
759
- set value(value) {
760
- this._value = value;
761
- // This is needed to keep the group list from resetting control values to the initial input value
762
- this.updateComponentValue(value);
763
- }
764
- get value() {
765
- return this._value;
712
+ this.group = input(...(ngDevMode ? [undefined, { debugName: "group" }] : []));
713
+ this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
714
+ this.component = input(...(ngDevMode ? [undefined, { debugName: "component" }] : []));
715
+ this.index = input(...(ngDevMode ? [undefined, { debugName: "index" }] : []));
716
+ effect(() => {
717
+ this.updateComponentValue(this.value());
718
+ });
766
719
  }
767
720
  async ngOnInit() {
768
- if (this.component) {
769
- /**
770
- * create component and set values from config on its instance
771
- */
772
- const componentRef = this.container.createComponent(this.component);
721
+ if (this.component()) {
722
+ const componentRef = this.container.createComponent(this.component());
723
+ this.componentRef = componentRef;
773
724
  this.componentInstance = componentRef.instance;
774
- this.componentInstance.index = this.index;
775
- this.updateComponentValue(this.value);
725
+ this.componentInstance.index = this.index();
726
+ this.updateComponentValue(this.value());
776
727
  }
777
728
  }
778
729
  updateComponentValue(value) {
779
- if (!this.componentInstance)
730
+ if (!this.componentRef)
780
731
  return;
781
- this.componentInstance.value = value;
782
- this.cdr.detectChanges();
732
+ this.componentRef.setInput('value', value);
783
733
  }
784
734
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprDisplayFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
785
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.6", type: CrisprDisplayFieldDirective, isStandalone: true, selector: "[crisprDisplayField]", inputs: { group: "group", value: "value", component: "component", index: "index" }, ngImport: i0 }); }
735
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.6", type: CrisprDisplayFieldDirective, isStandalone: true, selector: "[crisprDisplayField]", inputs: { group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: false, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
786
736
  }
787
737
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprDisplayFieldDirective, decorators: [{
788
738
  type: Directive,
@@ -790,15 +740,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
790
740
  selector: '[crisprDisplayField]',
791
741
  standalone: true,
792
742
  }]
793
- }], propDecorators: { group: [{
794
- type: Input
795
- }], value: [{
796
- type: Input
797
- }], component: [{
798
- type: Input
799
- }], index: [{
800
- type: Input
801
- }] } });
743
+ }], ctorParameters: () => [], propDecorators: { group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], component: [{ type: i0.Input, args: [{ isSignal: true, alias: "component", required: false }] }], index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: false }] }] } });
802
744
 
803
745
  const defaultConfig = {
804
746
  addButtonLabel: 'ADD ITEM',
@@ -807,7 +749,6 @@ const defaultConfig = {
807
749
  class FormGroupListComponent extends CrisprControlComponent {
808
750
  constructor() {
809
751
  super(...arguments);
810
- this.cdr = inject(ChangeDetectorRef);
811
752
  this.defaultConfig = defaultConfig;
812
753
  /**
813
754
  * By setting this to true when adding/removing items from array,
@@ -821,22 +762,19 @@ class FormGroupListComponent extends CrisprControlComponent {
821
762
  // TODO: this is required to ngFor of controls in template, must be a better way
822
763
  }
823
764
  setControlValue(values) {
824
- if (this.control()) {
765
+ const formArray = this.control();
766
+ if (formArray) {
825
767
  if (values?.length > 0) {
826
768
  // clear any existing values so that new values don't concatenate onto the old
827
- const currentValues = this.control().value;
769
+ const currentValues = formArray.value;
828
770
  if (currentValues.length) {
829
- this.control().clear();
771
+ formArray.clear();
830
772
  }
831
773
  values.forEach((value) => this.addGroup(value));
832
774
  }
833
775
  else if (this.config().displayInitialItem) {
834
776
  this.addGroup();
835
777
  }
836
- // needed to ensure new array items render
837
- setTimeout(() => {
838
- this.cdr.detectChanges();
839
- });
840
778
  }
841
779
  }
842
780
  clickDelete(index) {
@@ -848,14 +786,12 @@ class FormGroupListComponent extends CrisprControlComponent {
848
786
  this.addGroup();
849
787
  }
850
788
  addGroup(value = null) {
851
- this.control().push(createControlForType(this.config().itemConfig, value));
852
- // needed to ensure new array items render
853
- setTimeout(() => {
854
- this.cdr.detectChanges();
855
- });
789
+ const formArray = this.control();
790
+ formArray.push(createControlForType(this.config().itemConfig, value));
856
791
  }
857
792
  deleteGroup(index) {
858
- this.control().removeAt(index);
793
+ const formArray = this.control();
794
+ formArray.removeAt(index);
859
795
  }
860
796
  clickEditItem(index) {
861
797
  this.selectedIndex = index;
@@ -887,44 +823,34 @@ class SubGroupComponent extends CrisprControlComponent {
887
823
  super.ngOnInit();
888
824
  }
889
825
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
890
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SubGroupComponent, isStandalone: false, selector: "crispr-sub-group", usesInheritance: true, ngImport: i0, template: "<crispr-field-container [config]=\"config()\" [group]=\"group()\">\n @for (fieldConfig of config().fields; track fieldConfig) {\n <ng-container crisprField [value]=\"value | initialControlValue : fieldConfig\" [config]=\"fieldConfig\"\n [group]=\"control()\" [testIdPrefix]=\"testId()\">\n </ng-container>\n }\n</crispr-field-container>", styles: [""], dependencies: [{ kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "testIdPrefix", "value"] }, { kind: "component", type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }], preserveWhitespaces: true }); }
826
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SubGroupComponent, isStandalone: true, selector: "crispr-sub-group", usesInheritance: true, ngImport: i0, template: "<crispr-field-container [config]=\"config()\" [group]=\"group()\">\n @for (fieldConfig of config().fields; track fieldConfig) {\n <ng-container crisprField [value]=\"value | initialControlValue : fieldConfig\" [config]=\"fieldConfig\"\n [group]=\"control()\" [testIdPrefix]=\"testId()\">\n </ng-container>\n }\n</crispr-field-container>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "testIdPrefix", "value"] }, { kind: "component", type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { kind: "ngmodule", type: CrisprPipesModule }, { kind: "ngmodule", type: FormValidationHandlerModule }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
891
827
  }
892
828
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupComponent, decorators: [{
893
829
  type: Component,
894
- args: [{ selector: 'crispr-sub-group', standalone: false, template: "<crispr-field-container [config]=\"config()\" [group]=\"group()\">\n @for (fieldConfig of config().fields; track fieldConfig) {\n <ng-container crisprField [value]=\"value | initialControlValue : fieldConfig\" [config]=\"fieldConfig\"\n [group]=\"control()\" [testIdPrefix]=\"testId()\">\n </ng-container>\n }\n</crispr-field-container>" }]
830
+ args: [{ selector: 'crispr-sub-group', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
831
+ CommonModule,
832
+ ReactiveFormsModule,
833
+ CrisprFieldDirective,
834
+ FieldContainerComponent,
835
+ CrisprPipesModule,
836
+ FormValidationHandlerModule,
837
+ ], template: "<crispr-field-container [config]=\"config()\" [group]=\"group()\">\n @for (fieldConfig of config().fields; track fieldConfig) {\n <ng-container crisprField [value]=\"value | initialControlValue : fieldConfig\" [config]=\"fieldConfig\"\n [group]=\"control()\" [testIdPrefix]=\"testId()\">\n </ng-container>\n }\n</crispr-field-container>" }]
895
838
  }] });
896
839
 
840
+ /**
841
+ * @deprecated SubGroupComponent is now standalone. Import SubGroupComponent directly.
842
+ * This module will be removed in the next major version.
843
+ */
897
844
  class SubGroupModule {
898
845
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
899
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, declarations: [SubGroupComponent], imports: [CommonModule,
900
- CrisprFieldDirective,
901
- FieldContainerComponent,
902
- CrisprPipesModule,
903
- // TODO: Does this need to be here?
904
- FormValidationHandlerModule], exports: [SubGroupComponent] }); }
905
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, imports: [CommonModule,
906
- FieldContainerComponent,
907
- CrisprPipesModule,
908
- // TODO: Does this need to be here?
909
- FormValidationHandlerModule] }); }
846
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, imports: [SubGroupComponent], exports: [SubGroupComponent] }); }
847
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, imports: [SubGroupComponent] }); }
910
848
  }
911
849
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, decorators: [{
912
850
  type: NgModule,
913
851
  args: [{
914
- imports: [
915
- CommonModule,
916
- CrisprFieldDirective,
917
- FieldContainerComponent,
918
- CrisprPipesModule,
919
- // TODO: Does this need to be here?
920
- FormValidationHandlerModule
921
- ],
922
- exports: [
923
- SubGroupComponent
924
- ],
925
- declarations: [
926
- SubGroupComponent
927
- ]
852
+ imports: [SubGroupComponent],
853
+ exports: [SubGroupComponent],
928
854
  }]
929
855
  }] });
930
856
 
@@ -934,6 +860,9 @@ var index = /*#__PURE__*/Object.freeze({
934
860
  SubGroupModule: SubGroupModule
935
861
  });
936
862
 
863
+ /**
864
+ * @deprecated Use stanadlone CripsrFormComponent
865
+ */
937
866
  class CrisprFormsModule {
938
867
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
939
868
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, imports: [CommonModule,
@@ -979,4 +908,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
979
908
  */
980
909
 
981
910
  export { AbstractAutocompleteComponent as A, CrisprFieldComponent as C, DEFAULT_EMPTY_OPTIONS_MESSAGE as D, FieldContainerComponent as F, HeadingComponent as H, InfoComponent as I, SelectedFileComponent as S, CrisprControlComponent as a, buildFormGroupFromConfig as b, CrisprFieldDirective as c, ControlType as d, convertBytesToMb as e, FileDropzoneDirective as f, CrisprDisplayFieldComponent as g, CrisprFormComponent as h, CrisprFormsModule as i, FileUploadFieldComponent as j, allowedFileExtValidator as k, allowedFileType as l, callOptionsIfFunction as m, createControlForType as n, observablifyOptions as o, filterOptionsByLabel as p, isControlConfig as q, maxFileSizeValidator as r, valueIn as v };
982
- //# sourceMappingURL=tft-crispr-forms-tft-crispr-forms-Dhjn_QdV.mjs.map
911
+ //# sourceMappingURL=tft-crispr-forms-tft-crispr-forms-D-kHHD0p.mjs.map