@tft/crispr-forms 21.0.6 → 21.0.8

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-CTiwbP6g.mjs} +3 -3
  2. package/fesm2022/{tft-crispr-forms-autocomplete-field.component-BrFPYj9i.mjs.map → tft-crispr-forms-autocomplete-field.component-CTiwbP6g.mjs.map} +1 -1
  3. package/fesm2022/{tft-crispr-forms-index-1oUkFYPd.mjs → tft-crispr-forms-index-3WrRXaWV.mjs} +2 -2
  4. package/fesm2022/{tft-crispr-forms-index-1oUkFYPd.mjs.map → tft-crispr-forms-index-3WrRXaWV.mjs.map} +1 -1
  5. package/fesm2022/tft-crispr-forms-index-BFuufQjh.mjs +18 -0
  6. package/fesm2022/tft-crispr-forms-index-BFuufQjh.mjs.map +1 -0
  7. package/fesm2022/tft-crispr-forms-index-Ba-C0nF_.mjs +54 -0
  8. package/fesm2022/tft-crispr-forms-index-Ba-C0nF_.mjs.map +1 -0
  9. package/fesm2022/{tft-crispr-forms-index-hpO3y8-r.mjs → tft-crispr-forms-index-CCjdBVC7.mjs} +2 -2
  10. package/fesm2022/{tft-crispr-forms-index-hpO3y8-r.mjs.map → tft-crispr-forms-index-CCjdBVC7.mjs.map} +1 -1
  11. package/fesm2022/{tft-crispr-forms-index-HtH17liK.mjs → tft-crispr-forms-index-Cch_cBxr.mjs} +3 -3
  12. package/fesm2022/{tft-crispr-forms-index-HtH17liK.mjs.map → tft-crispr-forms-index-Cch_cBxr.mjs.map} +1 -1
  13. package/fesm2022/{tft-crispr-forms-index-CMJfbPJv.mjs → tft-crispr-forms-index-CmBSNzoP.mjs} +2 -2
  14. package/fesm2022/{tft-crispr-forms-index-CMJfbPJv.mjs.map → tft-crispr-forms-index-CmBSNzoP.mjs.map} +1 -1
  15. package/fesm2022/{tft-crispr-forms-index-BYfudl7n.mjs → tft-crispr-forms-index-D0dpKcvi.mjs} +5 -7
  16. package/fesm2022/tft-crispr-forms-index-D0dpKcvi.mjs.map +1 -0
  17. package/fesm2022/{tft-crispr-forms-index-BNGj_Q31.mjs → tft-crispr-forms-index-DA3brqkq.mjs} +3 -3
  18. package/fesm2022/{tft-crispr-forms-index-BNGj_Q31.mjs.map → tft-crispr-forms-index-DA3brqkq.mjs.map} +1 -1
  19. package/fesm2022/{tft-crispr-forms-index-B9tVg0fe.mjs → tft-crispr-forms-index-Dzx5A98j.mjs} +2 -2
  20. package/fesm2022/{tft-crispr-forms-index-B9tVg0fe.mjs.map → tft-crispr-forms-index-Dzx5A98j.mjs.map} +1 -1
  21. package/fesm2022/{tft-crispr-forms-index-SXLsJ2dx.mjs → tft-crispr-forms-index-MxoL7osu.mjs} +2 -2
  22. package/fesm2022/{tft-crispr-forms-index-SXLsJ2dx.mjs.map → tft-crispr-forms-index-MxoL7osu.mjs.map} +1 -1
  23. package/fesm2022/{tft-crispr-forms-index-BVUDqeAd.mjs → tft-crispr-forms-index-Rh3_5mZk.mjs} +3 -3
  24. package/fesm2022/{tft-crispr-forms-index-BVUDqeAd.mjs.map → tft-crispr-forms-index-Rh3_5mZk.mjs.map} +1 -1
  25. package/fesm2022/{tft-crispr-forms-index-CLSsoEGa.mjs → tft-crispr-forms-index-WCrUN4T4.mjs} +2 -2
  26. package/fesm2022/{tft-crispr-forms-index-CLSsoEGa.mjs.map → tft-crispr-forms-index-WCrUN4T4.mjs.map} +1 -1
  27. package/fesm2022/{tft-crispr-forms-index-By2zsul9.mjs → tft-crispr-forms-index-evHXy0wa.mjs} +2 -2
  28. package/fesm2022/{tft-crispr-forms-index-By2zsul9.mjs.map → tft-crispr-forms-index-evHXy0wa.mjs.map} +1 -1
  29. package/fesm2022/tft-crispr-forms-index-n6rbP8zG.mjs +2 -0
  30. package/fesm2022/tft-crispr-forms-index-n6rbP8zG.mjs.map +1 -0
  31. package/fesm2022/{tft-crispr-forms-index-Cch_yKzh.mjs → tft-crispr-forms-index-zOK3hAcJ.mjs} +3 -3
  32. package/fesm2022/{tft-crispr-forms-index-Cch_yKzh.mjs.map → tft-crispr-forms-index-zOK3hAcJ.mjs.map} +1 -1
  33. package/fesm2022/{tft-crispr-forms-tft-crispr-forms-Dhjn_QdV.mjs → tft-crispr-forms-tft-crispr-forms-Dxdiigcv.mjs} +154 -223
  34. package/fesm2022/tft-crispr-forms-tft-crispr-forms-Dxdiigcv.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-Ba-C0nF_.mjs').then(({ ButtonComponent }) => ButtonComponent),
315
+ input: () => import('./tft-crispr-forms-index-WCrUN4T4.mjs').then(({ InputFieldComponent }) => InputFieldComponent),
316
+ select: () => import('./tft-crispr-forms-index-DA3brqkq.mjs').then(({ SelectFieldComponent }) => SelectFieldComponent),
317
+ radio: () => import('./tft-crispr-forms-index-CCjdBVC7.mjs').then(({ RadioFieldComponent }) => RadioFieldComponent),
318
+ autocomplete: () => import('./tft-crispr-forms-index-n6rbP8zG.mjs').then(({ AutocompleteFieldComponent }) => AutocompleteFieldComponent),
319
+ autocompleteChiplist: () => import('./tft-crispr-forms-index-zOK3hAcJ.mjs').then(({ AutocompleteChiplistFieldComponent }) => AutocompleteChiplistFieldComponent),
320
+ map: () => import('./tft-crispr-forms-index-Rh3_5mZk.mjs').then(({ MapFieldComponent }) => MapFieldComponent),
321
+ textarea: () => import('./tft-crispr-forms-index-Dzx5A98j.mjs').then(({ TextareaFieldComponent }) => TextareaFieldComponent),
322
+ checkbox: () => import('./tft-crispr-forms-index-MxoL7osu.mjs').then(({ CheckboxFieldComponent }) => CheckboxFieldComponent),
323
+ slider: () => import('./tft-crispr-forms-index-evHXy0wa.mjs').then(({ SliderFieldComponent }) => SliderFieldComponent),
324
+ datepicker: () => import('./tft-crispr-forms-index-3WrRXaWV.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-D0dpKcvi.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-CmBSNzoP.mjs').then(({ DividerComponent }) => DividerComponent),
329
+ unitConversion: () => import('./tft-crispr-forms-index-Cch_cBxr.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
  }
@@ -616,41 +579,35 @@ class FieldContainerComponent {
616
579
  config.disabledCallback instanceof Function
617
580
  ? config.disabledCallback(group).pipe(
618
581
  // This enables/disables when callback conditions are met
619
- tap((shouldDisable) => shouldDisable ? control.disable() : control.enable()))
582
+ tap((shouldDisable) => shouldDisable
583
+ ? control.disable({ emitEvent: false })
584
+ : control.enable({ emitEvent: false })))
620
585
  : of(false);
621
586
  }
622
587
  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 }); }
588
+ 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
589
  }
625
590
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FieldContainerComponent, decorators: [{
626
591
  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
- }] } });
592
+ 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"] }]
593
+ }], 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
594
 
636
595
  class SelectedFileComponent {
596
+ constructor() {
597
+ this.fileName = input.required(...(ngDevMode ? [{ debugName: "fileName" }] : []));
598
+ this.progress = input(...(ngDevMode ? [undefined, { debugName: "progress" }] : []));
599
+ this.showProgress = input(...(ngDevMode ? [undefined, { debugName: "showProgress" }] : []));
600
+ this.color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : []));
601
+ }
637
602
  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 }); }
603
+ 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
604
  }
640
605
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SelectedFileComponent, decorators: [{
641
606
  type: Component,
642
- args: [{ selector: 'crispr-selected-file', imports: [
607
+ args: [{ selector: 'crispr-selected-file', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
643
608
  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
- }] } });
609
+ ], 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"] }]
610
+ }], 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
611
 
655
612
  /* eslint-disable @nx/enforce-module-boundaries */
656
613
  class FileUploadFieldComponent extends CrisprControlComponent {
@@ -754,35 +711,30 @@ var index$2 = /*#__PURE__*/Object.freeze({
754
711
  class CrisprDisplayFieldDirective {
755
712
  constructor() {
756
713
  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;
714
+ this.group = input(...(ngDevMode ? [undefined, { debugName: "group" }] : []));
715
+ this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
716
+ this.component = input(...(ngDevMode ? [undefined, { debugName: "component" }] : []));
717
+ this.index = input(...(ngDevMode ? [undefined, { debugName: "index" }] : []));
718
+ effect(() => {
719
+ this.updateComponentValue(this.value());
720
+ });
766
721
  }
767
722
  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);
723
+ if (this.component()) {
724
+ const componentRef = this.container.createComponent(this.component());
725
+ this.componentRef = componentRef;
773
726
  this.componentInstance = componentRef.instance;
774
- this.componentInstance.index = this.index;
775
- this.updateComponentValue(this.value);
727
+ this.componentInstance.index = this.index();
728
+ this.updateComponentValue(this.value());
776
729
  }
777
730
  }
778
731
  updateComponentValue(value) {
779
- if (!this.componentInstance)
732
+ if (!this.componentRef)
780
733
  return;
781
- this.componentInstance.value = value;
782
- this.cdr.detectChanges();
734
+ this.componentRef.setInput('value', value);
783
735
  }
784
736
  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 }); }
737
+ 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
738
  }
787
739
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprDisplayFieldDirective, decorators: [{
788
740
  type: Directive,
@@ -790,15 +742,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
790
742
  selector: '[crisprDisplayField]',
791
743
  standalone: true,
792
744
  }]
793
- }], propDecorators: { group: [{
794
- type: Input
795
- }], value: [{
796
- type: Input
797
- }], component: [{
798
- type: Input
799
- }], index: [{
800
- type: Input
801
- }] } });
745
+ }], 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
746
 
803
747
  const defaultConfig = {
804
748
  addButtonLabel: 'ADD ITEM',
@@ -807,7 +751,6 @@ const defaultConfig = {
807
751
  class FormGroupListComponent extends CrisprControlComponent {
808
752
  constructor() {
809
753
  super(...arguments);
810
- this.cdr = inject(ChangeDetectorRef);
811
754
  this.defaultConfig = defaultConfig;
812
755
  /**
813
756
  * By setting this to true when adding/removing items from array,
@@ -821,22 +764,19 @@ class FormGroupListComponent extends CrisprControlComponent {
821
764
  // TODO: this is required to ngFor of controls in template, must be a better way
822
765
  }
823
766
  setControlValue(values) {
824
- if (this.control()) {
767
+ const formArray = this.control();
768
+ if (formArray) {
825
769
  if (values?.length > 0) {
826
770
  // clear any existing values so that new values don't concatenate onto the old
827
- const currentValues = this.control().value;
771
+ const currentValues = formArray.value;
828
772
  if (currentValues.length) {
829
- this.control().clear();
773
+ formArray.clear();
830
774
  }
831
775
  values.forEach((value) => this.addGroup(value));
832
776
  }
833
777
  else if (this.config().displayInitialItem) {
834
778
  this.addGroup();
835
779
  }
836
- // needed to ensure new array items render
837
- setTimeout(() => {
838
- this.cdr.detectChanges();
839
- });
840
780
  }
841
781
  }
842
782
  clickDelete(index) {
@@ -848,14 +788,12 @@ class FormGroupListComponent extends CrisprControlComponent {
848
788
  this.addGroup();
849
789
  }
850
790
  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
- });
791
+ const formArray = this.control();
792
+ formArray.push(createControlForType(this.config().itemConfig, value));
856
793
  }
857
794
  deleteGroup(index) {
858
- this.control().removeAt(index);
795
+ const formArray = this.control();
796
+ formArray.removeAt(index);
859
797
  }
860
798
  clickEditItem(index) {
861
799
  this.selectedIndex = index;
@@ -887,44 +825,34 @@ class SubGroupComponent extends CrisprControlComponent {
887
825
  super.ngOnInit();
888
826
  }
889
827
  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 }); }
828
+ 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
829
  }
892
830
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupComponent, decorators: [{
893
831
  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>" }]
832
+ args: [{ selector: 'crispr-sub-group', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
833
+ CommonModule,
834
+ ReactiveFormsModule,
835
+ CrisprFieldDirective,
836
+ FieldContainerComponent,
837
+ CrisprPipesModule,
838
+ FormValidationHandlerModule,
839
+ ], 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
840
  }] });
896
841
 
842
+ /**
843
+ * @deprecated SubGroupComponent is now standalone. Import SubGroupComponent directly.
844
+ * This module will be removed in the next major version.
845
+ */
897
846
  class SubGroupModule {
898
847
  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] }); }
848
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, imports: [SubGroupComponent], exports: [SubGroupComponent] }); }
849
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, imports: [SubGroupComponent] }); }
910
850
  }
911
851
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, decorators: [{
912
852
  type: NgModule,
913
853
  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
- ]
854
+ imports: [SubGroupComponent],
855
+ exports: [SubGroupComponent],
928
856
  }]
929
857
  }] });
930
858
 
@@ -934,6 +862,9 @@ var index = /*#__PURE__*/Object.freeze({
934
862
  SubGroupModule: SubGroupModule
935
863
  });
936
864
 
865
+ /**
866
+ * @deprecated Use stanadlone CripsrFormComponent
867
+ */
937
868
  class CrisprFormsModule {
938
869
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
939
870
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, imports: [CommonModule,
@@ -979,4 +910,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
979
910
  */
980
911
 
981
912
  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
913
+ //# sourceMappingURL=tft-crispr-forms-tft-crispr-forms-Dxdiigcv.mjs.map