@tft/crispr-forms 21.0.18 → 21.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +21 -4
  2. package/fesm2022/tft-crispr-forms.mjs +2071 -1
  3. package/fesm2022/tft-crispr-forms.mjs.map +1 -1
  4. package/package.json +7 -7
  5. package/types/tft-crispr-forms.d.ts +238 -212
  6. package/fesm2022/tft-crispr-forms-autocomplete-field.component-BgQZYqB0.mjs +0 -95
  7. package/fesm2022/tft-crispr-forms-autocomplete-field.component-BgQZYqB0.mjs.map +0 -1
  8. package/fesm2022/tft-crispr-forms-index-3aw152gK.mjs +0 -18
  9. package/fesm2022/tft-crispr-forms-index-3aw152gK.mjs.map +0 -1
  10. package/fesm2022/tft-crispr-forms-index-BFzx83fR.mjs +0 -39
  11. package/fesm2022/tft-crispr-forms-index-BFzx83fR.mjs.map +0 -1
  12. package/fesm2022/tft-crispr-forms-index-BMZQakFs.mjs +0 -88
  13. package/fesm2022/tft-crispr-forms-index-BMZQakFs.mjs.map +0 -1
  14. package/fesm2022/tft-crispr-forms-index-B_lhA83w.mjs +0 -2
  15. package/fesm2022/tft-crispr-forms-index-B_lhA83w.mjs.map +0 -1
  16. package/fesm2022/tft-crispr-forms-index-BawhjTMp.mjs +0 -183
  17. package/fesm2022/tft-crispr-forms-index-BawhjTMp.mjs.map +0 -1
  18. package/fesm2022/tft-crispr-forms-index-CXXD0vdZ.mjs +0 -172
  19. package/fesm2022/tft-crispr-forms-index-CXXD0vdZ.mjs.map +0 -1
  20. package/fesm2022/tft-crispr-forms-index-CmVahfkJ.mjs +0 -24
  21. package/fesm2022/tft-crispr-forms-index-CmVahfkJ.mjs.map +0 -1
  22. package/fesm2022/tft-crispr-forms-index-CoUwTugQ.mjs +0 -309
  23. package/fesm2022/tft-crispr-forms-index-CoUwTugQ.mjs.map +0 -1
  24. package/fesm2022/tft-crispr-forms-index-D99OHDPc.mjs +0 -40
  25. package/fesm2022/tft-crispr-forms-index-D99OHDPc.mjs.map +0 -1
  26. package/fesm2022/tft-crispr-forms-index-DYWkX7D3.mjs +0 -83
  27. package/fesm2022/tft-crispr-forms-index-DYWkX7D3.mjs.map +0 -1
  28. package/fesm2022/tft-crispr-forms-index-DysioRya.mjs +0 -39
  29. package/fesm2022/tft-crispr-forms-index-DysioRya.mjs.map +0 -1
  30. package/fesm2022/tft-crispr-forms-index-GlYQbbbv.mjs +0 -36
  31. package/fesm2022/tft-crispr-forms-index-GlYQbbbv.mjs.map +0 -1
  32. package/fesm2022/tft-crispr-forms-index-UX-Wdyk1.mjs +0 -40
  33. package/fesm2022/tft-crispr-forms-index-UX-Wdyk1.mjs.map +0 -1
  34. package/fesm2022/tft-crispr-forms-index-bTdYHJPk.mjs +0 -68
  35. package/fesm2022/tft-crispr-forms-index-bTdYHJPk.mjs.map +0 -1
  36. package/fesm2022/tft-crispr-forms-index-kah2HT_N.mjs +0 -54
  37. package/fesm2022/tft-crispr-forms-index-kah2HT_N.mjs.map +0 -1
  38. package/fesm2022/tft-crispr-forms-tft-crispr-forms-8liD7eof.mjs +0 -943
  39. package/fesm2022/tft-crispr-forms-tft-crispr-forms-8liD7eof.mjs.map +0 -1
@@ -1,943 +0,0 @@
1
- import * as i0 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
- import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import * as i1$1 from '@angular/forms';
6
- import { FormArray, FormControl, FormGroup, ReactiveFormsModule, NgControl } from '@angular/forms';
7
- import * as i6 from '@tft/form-validation-handler';
8
- import { FormValidationHandlerModule } from '@tft/form-validation-handler';
9
- import { takeUntilDestroyed, outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
10
- import { map, startWith, debounceTime, distinctUntilChanged, switchMap, shareReplay, tap } from 'rxjs/operators';
11
- import { from, of, isObservable } from 'rxjs';
12
- import * as i1$3 from '@angular/material/button';
13
- import { MatButtonModule } from '@angular/material/button';
14
- import * as i2 from '@angular/material/icon';
15
- import { MatIconModule } from '@angular/material/icon';
16
- import * as i2$2 from '@angular/material/form-field';
17
- import { MatFormFieldModule } from '@angular/material/form-field';
18
- import * as i3 from '@angular/material/input';
19
- import { MatInputModule } from '@angular/material/input';
20
- import * as i2$1 from '@angular/material/tooltip';
21
- import { MatTooltipModule } from '@angular/material/tooltip';
22
- import * as i1$2 from '@angular/material/progress-bar';
23
- import { MatProgressBarModule } from '@angular/material/progress-bar';
24
-
25
- function valueIn(values) {
26
- return map((value) => {
27
- if (value) {
28
- return values.some(v => {
29
- if (isRegex(v)) {
30
- const trimmedStringForRegex = v.substr(1, v.length - 2);
31
- const regex = new RegExp(trimmedStringForRegex);
32
- return regex.test(value);
33
- }
34
- else {
35
- return v === value;
36
- }
37
- });
38
- }
39
- else {
40
- return false;
41
- }
42
- });
43
- }
44
- function isRegex(string) {
45
- return string.startsWith('/') && string.endsWith('/');
46
- }
47
-
48
- const DEFAULT_EMPTY_OPTIONS_MESSAGE = 'No Items';
49
-
50
- // export type ControlType = keyof typeof FIELD_COMPONENTS;
51
- var ControlType;
52
- (function (ControlType) {
53
- ControlType["AUTOCOMPLETE"] = "autocomplete";
54
- ControlType["AUTOCOMPLETE_CHIPLIST"] = "autocompleteChiplist";
55
- ControlType["BUTTON"] = "button";
56
- ControlType["CHECKBOX"] = "checkbox";
57
- ControlType["CUSTOM"] = "custom";
58
- ControlType["DATEPICKER"] = "datepicker";
59
- ControlType["DIVIDER"] = "divider";
60
- ControlType["FILE_UPLOAD"] = "fileUpload";
61
- ControlType["GROUP_LIST"] = "groupList";
62
- ControlType["HEADING"] = "heading";
63
- ControlType["IMAGE_UPLOAD"] = "imageUpload";
64
- ControlType["INPUT"] = "input";
65
- ControlType["MAP"] = "map";
66
- ControlType["RADIO"] = "radio";
67
- ControlType["SELECT"] = "select";
68
- ControlType["SLIDER"] = "slider";
69
- ControlType["SUB_GROUP"] = "subGroup";
70
- ControlType["TEXTAREA"] = "textarea";
71
- ControlType["UNIT_CONVERSION"] = "unitConversion";
72
- })(ControlType || (ControlType = {}));
73
-
74
- /**
75
- * Analyze the config and build a form control to spec. Notice we don't use FormBuilder here
76
- * as we want to keep this function pure.
77
- * @param controlConfig the configuration object for the control to build
78
- * @param value an initial value to use if passed in
79
- */
80
- function createControlForType(controlConfig, value = null) {
81
- // build form control out based on the control type
82
- const control = controlConfig.controlType === ControlType.SUB_GROUP
83
- ? buildFormGroupFromConfig(controlConfig, value)
84
- : controlConfig.controlType === ControlType.GROUP_LIST
85
- ? new FormArray([], controlConfig.validators)
86
- : new FormControl(value || null, controlConfig.validators);
87
- return control;
88
- }
89
-
90
- /**
91
- * Determines if the field config is for a form control (not a divider, heading or other non-control field)
92
- */
93
- function isControlConfig(fieldConfig) {
94
- return 'controlName' in fieldConfig;
95
- }
96
-
97
- /**
98
- * builds out form group based on config
99
- * @param config a configuration for a form group
100
- * @param value an object of initial values to pass in
101
- * @param group the form group to modify and build out
102
- */
103
- function buildFormGroupFromConfig(config, value = null, group = new FormGroup({})) {
104
- config.fields.forEach((controlConfig) => {
105
- if (isControlConfig(controlConfig)) {
106
- // then add a control to the group using the controlName from configuration
107
- const { controlName } = controlConfig;
108
- if (group.get(controlName)) {
109
- group.removeControl(controlName);
110
- }
111
- // if there's a value object and it has a non-null/undefined value for this field use it.
112
- // Otherwise, default to null
113
- const controlValue = (value && value[controlName]) ?? null;
114
- const control = createControlForType(controlConfig, controlValue);
115
- group.addControl(controlName, control);
116
- }
117
- });
118
- group.setValidators(config.validators);
119
- return group;
120
- }
121
-
122
- function callOptionsIfFunction(options, parentGroup, searchString) {
123
- return options instanceof Function ? options(parentGroup, searchString) : options;
124
- }
125
-
126
- /**
127
- * A basic filter function that filters the search string against the label of the options object
128
- * @param options the array of options to filter
129
- * @param searchString the string from the input
130
- */
131
- function filterOptionsByLabel(options, searchString) {
132
- return options.filter(option => {
133
- return option.label && option.label.toLowerCase().includes(searchString.toLowerCase());
134
- });
135
- }
136
-
137
- /**
138
- * The user can give us select options as an array, a function that resolves to a promise,
139
- * or an observable. This functions consumes any of those and returns an observable that
140
- * resolves an array of options
141
- *
142
- * @param options the options passed in from the config
143
- * @param emptyMessageOption the message to display when the array is empty
144
- */
145
- function observablifyOptions(options, parentGroup, searchString) {
146
- const calledOptions = callOptionsIfFunction(options, parentGroup, searchString);
147
- // if options are a promise
148
- const observableOptions = calledOptions instanceof Promise
149
- // convert to observable
150
- ? from(calledOptions)
151
- // if array that isn't empty
152
- : Array.isArray(calledOptions) && calledOptions.length
153
- // convert to observable
154
- ? of(calledOptions)
155
- // if observable
156
- : isObservable(calledOptions)
157
- // return it
158
- ? calledOptions
159
- // else an empty array
160
- : of([]);
161
- return observableOptions;
162
- }
163
-
164
- function convertBytesToMb(bytes) {
165
- return bytes / 1048576;
166
- }
167
- function maxFileSizeValidator(maxFileSize) {
168
- return (control) => {
169
- const controlValue = control.value;
170
- if (!(controlValue instanceof File)) {
171
- return null;
172
- }
173
- const actualFileSize = +convertBytesToMb(controlValue.size).toPrecision(3);
174
- if (maxFileSize > actualFileSize)
175
- return null;
176
- return { maxFileSize: { maxFileSize, actualFileSize } };
177
- };
178
- }
179
- function allowedFileExtValidator(allowedFileExtensions, onlyAllowFiles = true) {
180
- return (control) => {
181
- const controlValue = control.value;
182
- const isFile = controlValue instanceof File;
183
- if (!onlyAllowFiles && !isFile)
184
- return null;
185
- const actualExtension = isFile ? controlValue.name.split('.').pop().toLocaleLowerCase() : 'Not a file';
186
- const isAllowedExtension = allowedFileExtensions.includes(actualExtension);
187
- if (isAllowedExtension) {
188
- return null;
189
- }
190
- return { allowedExtension: { allowedFileExtensions, actualExtension } };
191
- };
192
- }
193
- function allowedFileType(matchExp) {
194
- return (formControl) => {
195
- const value = formControl.value;
196
- if (!(value instanceof File))
197
- return null;
198
- const type = value.type;
199
- const matches = type.match(matchExp);
200
- if (!type || !matches?.length) {
201
- return {
202
- allowedFileType: {
203
- actualType: type,
204
- allowedTypeExp: matchExp
205
- }
206
- };
207
- }
208
- else {
209
- return null;
210
- }
211
- };
212
- }
213
-
214
- class CrisprFieldComponent {
215
- constructor() {
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" }] : []));
221
- this.testIdPrefix = input(undefined, ...(ngDevMode ? [{ debugName: "testIdPrefix" }] : []));
222
- this.testId = computed(() => {
223
- const config = this.config();
224
- const id = config?.testId || config?.controlName;
225
- if (!id)
226
- return undefined;
227
- const prefix = this.testIdPrefix();
228
- return prefix ? `${prefix}.${id}` : id;
229
- }, ...(ngDevMode ? [{ debugName: "testId" }] : []));
230
- }
231
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
232
- 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 }); }
233
- }
234
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldComponent, decorators: [{
235
- type: Directive,
236
- args: [{
237
- standalone: true
238
- }]
239
- }], propDecorators: { inputConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], testIdPrefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "testIdPrefix", required: false }] }] } });
240
-
241
- class CrisprControlComponent extends CrisprFieldComponent {
242
- constructor() {
243
- super();
244
- this.destroyRef = inject(DestroyRef);
245
- this.group = input(null, ...(ngDevMode ? [{ debugName: "group" }] : []));
246
- this.control = computed(() => this.group()?.get(this.config().controlName), ...(ngDevMode ? [{ debugName: "control" }] : []));
247
- this.valueChanges = new EventEmitter();
248
- this.value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
249
- effect(() => {
250
- this.setControlValue(this.value());
251
- });
252
- }
253
- ngOnInit() {
254
- this.control().valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => {
255
- this.valueChanges.emit(value);
256
- });
257
- // setTimeouts are ugly but this seems to be the only way to get the computed field to compute initial values
258
- setTimeout(() => {
259
- this.control().updateValueAndValidity();
260
- });
261
- }
262
- setControlValue(value) {
263
- if (value && this.control() && this.config().controlType !== ControlType.SUB_GROUP) {
264
- this.control().setValue(value);
265
- }
266
- }
267
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
268
- 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 }); }
269
- }
270
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprControlComponent, decorators: [{
271
- type: Directive,
272
- args: [{
273
- standalone: true
274
- }]
275
- }], ctorParameters: () => [], propDecorators: { group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], valueChanges: [{
276
- type: Output
277
- }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
278
-
279
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
280
- class AbstractAutocompleteComponent extends CrisprControlComponent {
281
- constructor() {
282
- super(...arguments);
283
- // we need a separate control for the UI because of the way the material autocomplete chiplist works
284
- this.autocompleteInputControl = new FormControl('');
285
- // Narrows the parent's computed config type to include C-specific properties (e.g. chiplist-only fields)
286
- // Must re-implement the defaultConfig merge from CrisprFieldComponent because this override replaces it.
287
- this.config = computed(() => {
288
- const c = this.inputConfig();
289
- return (c && this.defaultConfig)
290
- ? { ...this.defaultConfig, ...c }
291
- : c;
292
- }, ...(ngDevMode ? [{ debugName: "config" }] : []));
293
- }
294
- ngOnInit() {
295
- super.ngOnInit();
296
- this.group().addControl(this.config().controlName, new FormControl());
297
- // filter options by the search string using either the default filter function or one passed in through config()
298
- this.options$ = this.autocompleteInputControl.valueChanges.pipe(
299
- // this is needed to have the options panel to open on focus
300
- startWith(''), debounceTime(this.config().typeDebounceTime), map((searchText) => typeof searchText === 'string' ? searchText?.trim() : ''), distinctUntilChanged(), switchMap((searchText) => observablifyOptions(this.config().options, this.group(), searchText)), shareReplay(1));
301
- }
302
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: AbstractAutocompleteComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
303
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.6", type: AbstractAutocompleteComponent, isStandalone: true, usesInheritance: true, ngImport: i0 }); }
304
- }
305
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: AbstractAutocompleteComponent, decorators: [{
306
- type: Directive
307
- }] });
308
-
309
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
310
- class CrisprDisplayFieldComponent extends CrisprControlComponent {
311
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprDisplayFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
312
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.6", type: CrisprDisplayFieldComponent, isStandalone: true, usesInheritance: true, ngImport: i0 }); }
313
- }
314
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprDisplayFieldComponent, decorators: [{
315
- type: Directive
316
- }] });
317
-
318
- const FIELD_COMPONENTS = {
319
- groupList: () => Promise.resolve().then(function () { return index$1; }).then(({ FormGroupListComponent }) => FormGroupListComponent),
320
- subGroup: () => Promise.resolve().then(function () { return index; }).then(({ SubGroupComponent }) => SubGroupComponent),
321
- button: () => import('./tft-crispr-forms-index-kah2HT_N.mjs').then(({ ButtonComponent }) => ButtonComponent),
322
- input: () => import('./tft-crispr-forms-index-UX-Wdyk1.mjs').then(({ InputFieldComponent }) => InputFieldComponent),
323
- select: () => import('./tft-crispr-forms-index-DYWkX7D3.mjs').then(({ SelectFieldComponent }) => SelectFieldComponent),
324
- radio: () => import('./tft-crispr-forms-index-D99OHDPc.mjs').then(({ RadioFieldComponent }) => RadioFieldComponent),
325
- autocomplete: () => import('./tft-crispr-forms-index-B_lhA83w.mjs').then(({ AutocompleteFieldComponent }) => AutocompleteFieldComponent),
326
- autocompleteChiplist: () => import('./tft-crispr-forms-index-BawhjTMp.mjs').then(({ AutocompleteChiplistFieldComponent }) => AutocompleteChiplistFieldComponent),
327
- map: () => import('./tft-crispr-forms-index-CXXD0vdZ.mjs').then(({ MapFieldComponent }) => MapFieldComponent),
328
- textarea: () => import('./tft-crispr-forms-index-DysioRya.mjs').then(({ TextareaFieldComponent }) => TextareaFieldComponent),
329
- checkbox: () => import('./tft-crispr-forms-index-BFzx83fR.mjs').then(({ CheckboxFieldComponent }) => CheckboxFieldComponent),
330
- slider: () => import('./tft-crispr-forms-index-GlYQbbbv.mjs').then(({ SliderFieldComponent }) => SliderFieldComponent),
331
- datepicker: () => import('./tft-crispr-forms-index-bTdYHJPk.mjs').then(({ DatepickerFieldComponent }) => DatepickerFieldComponent),
332
- fileUpload: () => Promise.resolve().then(function () { return index$3; }).then(({ FileUploadFieldComponent }) => FileUploadFieldComponent),
333
- imageUpload: () => import('./tft-crispr-forms-index-CoUwTugQ.mjs').then(({ ImageUploadFieldComponent }) => ImageUploadFieldComponent),
334
- heading: () => Promise.resolve().then(function () { return index$2; }).then(({ HeadingComponent }) => HeadingComponent),
335
- divider: () => import('./tft-crispr-forms-index-CmVahfkJ.mjs').then(({ DividerComponent }) => DividerComponent),
336
- unitConversion: () => import('./tft-crispr-forms-index-BMZQakFs.mjs').then(({ UnitConversionFieldComponent }) => UnitConversionFieldComponent),
337
- };
338
- function isControlComponent(component) {
339
- return component && isControlConfig(component.config()) && 'value' in component;
340
- }
341
- function isControlOrButtonComponent(component) {
342
- return (isControlComponent(component) ||
343
- component.config().controlType === ControlType.BUTTON);
344
- }
345
-
346
- class CrisprFieldDirective {
347
- constructor() {
348
- this.config = input(...(ngDevMode ? [undefined, { debugName: "config" }] : []));
349
- this.group = input(...(ngDevMode ? [undefined, { debugName: "group" }] : []));
350
- this.testIdPrefix = input(undefined, ...(ngDevMode ? [{ debugName: "testIdPrefix" }] : []));
351
- this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
352
- this.container = inject(ViewContainerRef);
353
- this.renderer = inject(Renderer2);
354
- effect(() => {
355
- this.updateComponentValue(this.value());
356
- });
357
- }
358
- async ngOnInit() {
359
- const component = this.config().component ||
360
- (await FIELD_COMPONENTS[this.config().controlType]());
361
- this.componentRef =
362
- this.container.createComponent(component);
363
- this.component = this.componentRef.instance;
364
- this.componentRef.setInput('config', this.config());
365
- if (isControlOrButtonComponent(this.component)) {
366
- this.componentRef.setInput('group', this.group());
367
- }
368
- this.componentRef.setInput('testIdPrefix', this.testIdPrefix());
369
- this.updateComponentValue(this.value());
370
- if (!this.config().classes)
371
- return;
372
- this.config().classes.forEach((klass) => {
373
- if (klass.includes(' ')) {
374
- throw Error(`Improperly formatted class. '${klass}' cannot contain spaces.`);
375
- }
376
- else {
377
- this.renderer.addClass(this.componentRef.location.nativeElement, klass);
378
- }
379
- });
380
- }
381
- updateComponentValue(value) {
382
- if (this.componentRef && isControlComponent(this.component)) {
383
- this.componentRef.setInput('value', value);
384
- }
385
- }
386
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
387
- 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 }); }
388
- }
389
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFieldDirective, decorators: [{
390
- type: Directive,
391
- args: [{
392
- selector: '[crisprField]',
393
- standalone: true,
394
- }]
395
- }], 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 }] }] } });
396
-
397
- class InitialControlValuePipe {
398
- // TODO: does changing any to unknown break anything?
399
- transform(initialFormValue, fieldConfig) {
400
- return initialFormValue && isControlConfig(fieldConfig)
401
- ? initialFormValue[fieldConfig.controlName] || null
402
- : null;
403
- }
404
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: InitialControlValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
405
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: InitialControlValuePipe, isStandalone: false, name: "initialControlValue" }); }
406
- }
407
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: InitialControlValuePipe, decorators: [{
408
- type: Pipe,
409
- args: [{
410
- name: 'initialControlValue',
411
- standalone: false
412
- }]
413
- }] });
414
-
415
- class CrisprPipesModule {
416
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprPipesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
417
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: CrisprPipesModule, declarations: [InitialControlValuePipe], imports: [CommonModule], exports: [InitialControlValuePipe] }); }
418
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprPipesModule, imports: [CommonModule] }); }
419
- }
420
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprPipesModule, decorators: [{
421
- type: NgModule,
422
- args: [{
423
- imports: [
424
- CommonModule
425
- ],
426
- exports: [
427
- InitialControlValuePipe
428
- ],
429
- declarations: [
430
- InitialControlValuePipe
431
- ]
432
- }]
433
- }] });
434
-
435
- class CrisprFormComponent {
436
- constructor() {
437
- this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
438
- this.form = input(new FormGroup({}), ...(ngDevMode ? [{ debugName: "form" }] : []));
439
- this.value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
440
- this.submitted = output();
441
- /** Patch form values whenever the [value] input changes without firing valueChanges. */
442
- this.patchValueEffect = effect(() => {
443
- const value = this.value();
444
- untracked(() => {
445
- if (value) {
446
- this.form().patchValue(value, { emitEvent: false });
447
- }
448
- });
449
- }, ...(ngDevMode ? [{ debugName: "patchValueEffect" }] : []));
450
- // proxy value and status change events through to consuming component
451
- this.valueChanges = outputFromObservable(toObservable(this.form).pipe(switchMap((f) => f.valueChanges)));
452
- this.statusChanges = outputFromObservable(toObservable(this.form).pipe(switchMap((f) => f.statusChanges)));
453
- }
454
- ngOnInit() {
455
- // build out the form, note that we pass in the form as the third argument and the function modifies it
456
- buildFormGroupFromConfig(this.config(), this.value(), this.form());
457
- }
458
- handleSubmit() {
459
- this.form().markAllAsTouched();
460
- this.submitted.emit(this.form());
461
- }
462
- triggerSubmit() {
463
- this.submitTrigger.nativeElement.click();
464
- }
465
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
466
- 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" }, host: { properties: { "attr.data-density": "config().density ?? null" } }, 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}:host[data-density=\"-1\"] ::ng-deep{--mat-form-field-container-height: 52px;--mat-form-field-filled-label-display: block;--mat-form-field-container-vertical-padding: 14px;--mat-form-field-filled-with-label-container-padding-top: 22px;--mat-form-field-filled-with-label-container-padding-bottom: 6px;--mat-select-arrow-transform: translateY(-8px)}:host[data-density=\"-1\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-1\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-1\"] ::ng-deep{--mat-checkbox-touch-target-display: block;--mat-checkbox-state-layer-size: 36px;--mat-radio-state-layer-size: 36px;--mat-radio-touch-target-display: block;--mat-button-filled-container-height: 32px;--mat-button-filled-touch-target-display: block;--mat-button-outlined-container-height: 32px;--mat-button-outlined-touch-target-display: block;--mat-button-protected-container-height: 32px;--mat-button-protected-touch-target-display: block;--mat-button-text-container-height: 32px;--mat-button-text-touch-target-display: block;--mat-button-tonal-container-height: 32px;--mat-button-tonal-touch-target-display: block;--mat-icon-button-touch-target-display: block}:host[data-density=\"-1\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 44px;--mat-icon-button-state-layer-size: 44px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:10px}:host[data-density=\"-2\"] ::ng-deep{--mat-form-field-container-height: 48px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 12px;--mat-form-field-filled-with-label-container-padding-top: 12px;--mat-form-field-filled-with-label-container-padding-bottom: 12px;--mat-select-arrow-transform: none}:host[data-density=\"-2\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-2\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-2\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 32px;--mat-radio-state-layer-size: 32px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 28px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 28px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 28px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 28px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 28px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-2\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-3\"] ::ng-deep{--mat-form-field-container-height: 44px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 10px;--mat-form-field-filled-with-label-container-padding-top: 10px;--mat-form-field-filled-with-label-container-padding-bottom: 10px;--mat-select-arrow-transform: none}:host[data-density=\"-3\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-3\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-3\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 28px;--mat-radio-state-layer-size: 28px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-3\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 36px;--mat-icon-button-state-layer-size: 36px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:6px}:host[data-density=\"-4\"] ::ng-deep{--mat-form-field-container-height: 40px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 8px;--mat-form-field-filled-with-label-container-padding-top: 8px;--mat-form-field-filled-with-label-container-padding-bottom: 8px;--mat-select-arrow-transform: none}:host[data-density=\"-4\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-4\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-4\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 28px;--mat-radio-state-layer-size: 28px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-4\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 32px;--mat-icon-button-state-layer-size: 32px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:4px}:host[data-density=\"-5\"] ::ng-deep{--mat-form-field-container-height: 36px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 6px;--mat-form-field-filled-with-label-container-padding-top: 6px;--mat-form-field-filled-with-label-container-padding-bottom: 6px;--mat-select-arrow-transform: none}:host[data-density=\"-5\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-5\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-5\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 28px;--mat-radio-state-layer-size: 28px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-5\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 28px;--mat-icon-button-state-layer-size: 28px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:2px}\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 }); }
467
- }
468
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormComponent, decorators: [{
469
- type: Component,
470
- args: [{ selector: 'crispr-form', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, host: {
471
- '[attr.data-density]': 'config().density ?? null',
472
- }, imports: [
473
- CommonModule,
474
- CrisprFieldDirective,
475
- ReactiveFormsModule,
476
- FormValidationHandlerModule,
477
- CrisprPipesModule,
478
- ], 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}:host[data-density=\"-1\"] ::ng-deep{--mat-form-field-container-height: 52px;--mat-form-field-filled-label-display: block;--mat-form-field-container-vertical-padding: 14px;--mat-form-field-filled-with-label-container-padding-top: 22px;--mat-form-field-filled-with-label-container-padding-bottom: 6px;--mat-select-arrow-transform: translateY(-8px)}:host[data-density=\"-1\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-1\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-1\"] ::ng-deep{--mat-checkbox-touch-target-display: block;--mat-checkbox-state-layer-size: 36px;--mat-radio-state-layer-size: 36px;--mat-radio-touch-target-display: block;--mat-button-filled-container-height: 32px;--mat-button-filled-touch-target-display: block;--mat-button-outlined-container-height: 32px;--mat-button-outlined-touch-target-display: block;--mat-button-protected-container-height: 32px;--mat-button-protected-touch-target-display: block;--mat-button-text-container-height: 32px;--mat-button-text-touch-target-display: block;--mat-button-tonal-container-height: 32px;--mat-button-tonal-touch-target-display: block;--mat-icon-button-touch-target-display: block}:host[data-density=\"-1\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 44px;--mat-icon-button-state-layer-size: 44px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:10px}:host[data-density=\"-2\"] ::ng-deep{--mat-form-field-container-height: 48px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 12px;--mat-form-field-filled-with-label-container-padding-top: 12px;--mat-form-field-filled-with-label-container-padding-bottom: 12px;--mat-select-arrow-transform: none}:host[data-density=\"-2\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-2\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-2\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 32px;--mat-radio-state-layer-size: 32px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 28px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 28px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 28px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 28px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 28px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-2\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-3\"] ::ng-deep{--mat-form-field-container-height: 44px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 10px;--mat-form-field-filled-with-label-container-padding-top: 10px;--mat-form-field-filled-with-label-container-padding-bottom: 10px;--mat-select-arrow-transform: none}:host[data-density=\"-3\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-3\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-3\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 28px;--mat-radio-state-layer-size: 28px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-3\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 36px;--mat-icon-button-state-layer-size: 36px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:6px}:host[data-density=\"-4\"] ::ng-deep{--mat-form-field-container-height: 40px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 8px;--mat-form-field-filled-with-label-container-padding-top: 8px;--mat-form-field-filled-with-label-container-padding-bottom: 8px;--mat-select-arrow-transform: none}:host[data-density=\"-4\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-4\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-4\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 28px;--mat-radio-state-layer-size: 28px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-4\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 32px;--mat-icon-button-state-layer-size: 32px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:4px}:host[data-density=\"-5\"] ::ng-deep{--mat-form-field-container-height: 36px;--mat-form-field-filled-label-display: none;--mat-form-field-container-vertical-padding: 6px;--mat-form-field-filled-with-label-container-padding-top: 6px;--mat-form-field-filled-with-label-container-padding-bottom: 6px;--mat-select-arrow-transform: none}:host[data-density=\"-5\"] ::ng-deep .mat-calendar-controls{--mat-icon-button-touch-target-display: none}:host[data-density=\"-5\"] ::ng-deep .mat-calendar-controls .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 40px;--mat-icon-button-state-layer-size: 40px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:8px}:host[data-density=\"-5\"] ::ng-deep{--mat-checkbox-touch-target-display: none;--mat-checkbox-state-layer-size: 28px;--mat-radio-state-layer-size: 28px;--mat-radio-touch-target-display: none;--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none;--mat-icon-button-touch-target-display: none}:host[data-density=\"-5\"] ::ng-deep .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 28px;--mat-icon-button-state-layer-size: 28px;width:var(--mat-icon-button-state-layer-size);height:var(--mat-icon-button-state-layer-size);padding:2px}\n"] }]
479
- }], 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: [{
480
- type: ViewChild,
481
- args: ['submitTrigger']
482
- }] } });
483
-
484
- class FileDropzoneDirective {
485
- constructor() {
486
- this.fileDrop = new EventEmitter();
487
- this.crisprFileDropzone = true;
488
- }
489
- onDrop($event) {
490
- if (this.crisprFileDropzone) {
491
- $event.preventDefault();
492
- this.fileDrop.emit($event.dataTransfer.files);
493
- }
494
- }
495
- // Prevents DOM from trying to open file in browser
496
- onDragOver($event) {
497
- if (this.crisprFileDropzone) {
498
- $event.preventDefault();
499
- }
500
- }
501
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FileDropzoneDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
502
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.6", type: FileDropzoneDirective, isStandalone: true, selector: "[crisprFileDropzone]", inputs: { crisprFileDropzone: "crisprFileDropzone" }, outputs: { fileDrop: "fileDrop" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)" } }, ngImport: i0 }); }
503
- }
504
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FileDropzoneDirective, decorators: [{
505
- type: Directive,
506
- args: [{
507
- selector: '[crisprFileDropzone]',
508
- standalone: true,
509
- }]
510
- }], propDecorators: { fileDrop: [{
511
- type: Output
512
- }], crisprFileDropzone: [{
513
- type: Input
514
- }], onDrop: [{
515
- type: HostListener,
516
- args: ['drop', ['$event']]
517
- }], onDragOver: [{
518
- type: HostListener,
519
- args: ['dragover', ['$event']]
520
- }] } });
521
-
522
- class InfoComponent {
523
- constructor() {
524
- this.info = input.required(...(ngDevMode ? [{ debugName: "info" }] : []));
525
- }
526
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: InfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
527
- 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 }); }
528
- }
529
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: InfoComponent, decorators: [{
530
- type: Component,
531
- args: [{ selector: 'crispr-info', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
532
- MatIconModule,
533
- MatTooltipModule
534
- ], 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"] }]
535
- }], propDecorators: { info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: true }] }] } });
536
-
537
- const defaultConfig$1 = {
538
- typographyClass: 'mat-h3',
539
- };
540
- class HeadingComponent extends CrisprFieldComponent {
541
- constructor() {
542
- super(...arguments);
543
- this.defaultConfig = defaultConfig$1;
544
- }
545
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: HeadingComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
546
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: HeadingComponent, isStandalone: true, selector: "crispr-heading", usesInheritance: true, ngImport: i0, template: "@if (!!config()?.label) {\n <label\n [ngClass]=\"config().typographyClass\">\n {{ config().label }}\n @if (config().info) {\n <crispr-info\n matSuffix\n [info]=\"config().info\">\n </crispr-info>\n }\n </label>\n}\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i2$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: InfoComponent, selector: "crispr-info", inputs: ["info"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
547
- }
548
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: HeadingComponent, decorators: [{
549
- type: Component,
550
- args: [{ selector: 'crispr-heading', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, MatFormFieldModule, InfoComponent], standalone: true, template: "@if (!!config()?.label) {\n <label\n [ngClass]=\"config().typographyClass\">\n {{ config().label }}\n @if (config().info) {\n <crispr-info\n matSuffix\n [info]=\"config().info\">\n </crispr-info>\n }\n </label>\n}\n", styles: [":host{display:block}\n"] }]
551
- }] });
552
-
553
- class FieldContainerComponent {
554
- constructor() {
555
- // the configuration object for the field
556
- this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
557
- // the parent formGroup
558
- this.group = input.required(...(ngDevMode ? [{ debugName: "group" }] : []));
559
- // boolean whether field-container is inline
560
- this.inlineField = input(false, ...(ngDevMode ? [{ debugName: "inlineField" }] : []));
561
- this.isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
562
- this.isHidden = computed(() => this.isDisabled() && !!this.config().hideDisabled, ...(ngDevMode ? [{ debugName: "isHidden" }] : []));
563
- this.subs = [];
564
- }
565
- ngOnInit() {
566
- this.disabled$ = this.connectDisabledCallback(this.group(), this.config());
567
- this.subs.push(this.disabled$.subscribe(disabled => this.isDisabled.set(disabled)));
568
- // we tried moving this into afterViewChecked and afterContentChecked lifecycle hooks without any luck
569
- if (this.config().computeValue) {
570
- this.subs.push(this.config()
571
- .computeValue(this.group())
572
- .pipe(distinctUntilChanged(), tap((computedValue) => this.group().get(this.config().controlName).setValue(computedValue)))
573
- .subscribe());
574
- }
575
- }
576
- ngOnDestroy() {
577
- this.subs.forEach((sub) => sub.unsubscribe);
578
- }
579
- /**
580
- * Connects user defined disabledCallback function to the the view, so that the control is enabled/disabled
581
- * appropriately. It also will hide disabled fields in the UI unless `hideDisabled` is set to
582
- * false in the controls config
583
- * @param group used to get valueChanges from control
584
- * @param config configuration object used to
585
- */
586
- connectDisabledCallback(group, config = null) {
587
- const control = group.get(config.controlName);
588
- // If the disabled$ function exists on the field config then call it with the disabledCallbackConfig
589
- // as a parameter otherwise return an observable of true.
590
- return config?.disabledCallback &&
591
- config.disabledCallback instanceof Function
592
- ? config.disabledCallback(group).pipe(
593
- // This enables/disables when callback conditions are met
594
- tap((shouldDisable) => shouldDisable
595
- ? control.disable({ emitEvent: false })
596
- : control.enable({ emitEvent: false })))
597
- : of(false);
598
- }
599
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FieldContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
600
- 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 } }, host: { properties: { "style.display": "isHidden() ? \"none\" : \"\"" } }, ngImport: i0, template: "@if (!isHidden()) {\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" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
601
- }
602
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FieldContainerComponent, decorators: [{
603
- type: Component,
604
- args: [{ selector: 'crispr-field-container', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, HeadingComponent], host: {
605
- '[style.display]': 'isHidden() ? "none" : ""',
606
- }, template: "@if (!isHidden()) {\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"] }]
607
- }], 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 }] }] } });
608
-
609
- class SelectedFileComponent {
610
- constructor() {
611
- this.fileName = input.required(...(ngDevMode ? [{ debugName: "fileName" }] : []));
612
- this.progress = input(...(ngDevMode ? [undefined, { debugName: "progress" }] : []));
613
- this.showProgress = input(...(ngDevMode ? [undefined, { debugName: "showProgress" }] : []));
614
- this.color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : []));
615
- }
616
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SelectedFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
617
- 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 }); }
618
- }
619
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SelectedFileComponent, decorators: [{
620
- type: Component,
621
- args: [{ selector: 'crispr-selected-file', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
622
- MatProgressBarModule
623
- ], 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"] }]
624
- }], 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 }] }] } });
625
-
626
- /* eslint-disable @nx/enforce-module-boundaries */
627
- class FileUploadFieldComponent extends CrisprControlComponent {
628
- /**
629
- * Plain boolean view of `uploaded`, kept only for the public `AbstractUploadComponent` contract so
630
- * consumers of the `uploadFiles` callback can still read and assign `isUploaded`.
631
- * Internal code and the template use the `uploaded` signal directly.
632
- */
633
- get isUploaded() {
634
- return this.uploaded();
635
- }
636
- set isUploaded(value) {
637
- this.uploaded.set(value);
638
- }
639
- // ngControl: NgControl = null;
640
- constructor() {
641
- super();
642
- this.ngControl = inject(NgControl, { optional: true, self: true });
643
- this.defaultConfig = {
644
- allowMultipleFiles: false,
645
- acceptedTypes: '*.*',
646
- dropZoneText: 'DROP FILE HERE',
647
- selectFilesButtonType: 'button',
648
- selectButtonText: 'SELECT',
649
- showClearFilesButton: true,
650
- clearFilesButtonText: 'CLEAR',
651
- uploadButtonText: 'UPLOAD',
652
- uploadButtonType: 'button',
653
- showUploadProgress: false,
654
- disableOnUpload: true,
655
- };
656
- this.selectedFiles = signal(null, ...(ngDevMode ? [{ debugName: "selectedFiles" }] : []));
657
- this.selectedFilesArray = computed(() => this.selectedFiles() ? Array.from(this.selectedFiles()) : [], ...(ngDevMode ? [{ debugName: "selectedFilesArray" }] : []));
658
- /**
659
- * Whether the files have been uploaded. A signal so that changes made asynchronously (e.g. from the
660
- * `uploadFiles` callback once an upload finishes) re-render the OnPush/zoneless component.
661
- */
662
- this.uploaded = signal(false, ...(ngDevMode ? [{ debugName: "uploaded" }] : []));
663
- this.fileProgress = [];
664
- const ngControl = this.ngControl;
665
- if (this.ngControl != null) {
666
- // Setting the value accessor directly (instead of using
667
- // the providers) to avoid running into a circular import.
668
- ngControl.valueAccessor = this;
669
- }
670
- }
671
- ngOnInit() {
672
- super.ngOnInit();
673
- this.disabled$ = this.config().disabledCallback
674
- ? this.config().disabledCallback(this.group())
675
- : of(false);
676
- }
677
- filesChanged(files) {
678
- if (files && files.length > 0) {
679
- this.selectedFiles.set(files);
680
- this.control().patchValue(files);
681
- this.config().filesChanged?.(this.group(), files);
682
- }
683
- }
684
- uploadFiles() {
685
- if (this.selectedFiles() && this.config().uploadFiles) {
686
- this.uploaded.set(true);
687
- this.config().uploadFiles(this.group(), this.selectedFiles(), this);
688
- }
689
- }
690
- resetFileInput() {
691
- this.fileInputRef.nativeElement.value = '';
692
- this.control().patchValue(null);
693
- this.uploaded.set(false);
694
- }
695
- writeValue(value) {
696
- // clear file input
697
- // this.host.nativeElement.value = '';
698
- // this.file = null;
699
- }
700
- registerOnChange(fn) {
701
- this.onChange = fn;
702
- }
703
- registerOnTouched(fn) { }
704
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FileUploadFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
705
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: FileUploadFieldComponent, isStandalone: true, selector: "crispr-file-upload-field", viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config()\"\n [group]=\"group()\">\n <mat-form-field floatLabel=\"always\"\n [attr.data-testid]=\"testId()\"\n [color]=\"config().color\"\n appearance=\"outline\"\n [crisprFileDropzone]=\"!(disabled$ | async) && !(config().disableOnUpload && uploaded())\"\n [formGroup]=\"group()\"\n (fileDrop)=\"filesChanged($event)\">\n\n <input [formControlName]=\"config().controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n style=\"display: none\"\n [accept]=\"config().acceptedTypes\"\n [multiple]=\"config().allowMultipleFiles\"\n (change)=\"filesChanged($event.target.files)\"/>\n <mat-label>{{config().label}}</mat-label>\n\n @if (!selectedFiles() || selectedFiles().length === 0) {\n <div class=\"drop-info\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config().dropZoneText}}</h2>\n or\n <button\n mat-raised-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async) || config().disableOnUpload && uploaded()\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config().controlName\">\n {{config().selectButtonText}}\n </button>\n </div>\n } @else {\n <div class=\"selected-files-container\">\n <div class=\"selected-files-list\">\n @for (file of selectedFilesArray(); track file; let i = $index) {\n <crispr-selected-file\n [color]=\"config().color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"file.name\"\n [showProgress]=\"config().showUploadProgress\"\n [progress]=\"fileProgress && (fileProgress[i] | async)\">\n </crispr-selected-file>\n }\n </div>\n </div>\n }\n @if (config().hint && (control().valid || !control().touched)) {<mat-hint>{{config().hint}}</mat-hint>}\n </mat-form-field>\n @if ((selectedFiles())?.length > 0) {\n <div class=\"button-container\">\n <button\n mat-button\n (click)=\"resetFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async) || (config().disableOnUpload && uploaded())\"\n aria-label=\"Remove Selected File(s)\">\n {{config().clearFilesButtonText}}\n <mat-icon>delete</mat-icon>\n </button>\n @if (!!config().uploadFiles) {\n <button\n mat-raised-button\n type=\"button\"\n color=\"accent\"\n class=\"file-input-button\"\n [disabled]=\"(disabled$ | async) || (config().disableOnUpload && uploaded())\"\n (click)=\"uploadFiles()\"\n [attr.aria-label]=\"config().uploadButtonText\">\n {{ config().uploadButtonText }}\n </button>\n }\n </div>\n }\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-mdc-form-field .mat-mdc-form-field-infix{padding-top:0;display:flex;justify-content:center}:host .drop-info{display:flex;flex-direction:column;align-items:center}:host .drop-info .drop-icon{font-size:36px}:host .drop-info .mat-h2{margin:0}:host .button-container{display:flex;justify-content:flex-end;margin-top:-16px}:host .button-container button{margin-left:8px}:host .selected-files-container{width:100%}:host [matInput]{position:absolute;max-height:0;visibility:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { 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: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: SelectedFileComponent, selector: "crispr-selected-file", inputs: ["fileName", "progress", "showProgress", "color"] }, { kind: "ngmodule", type: FormValidationHandlerModule }, { kind: "directive", type: i6.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { kind: "directive", type: i6.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { kind: "directive", type: FileDropzoneDirective, selector: "[crisprFileDropzone]", inputs: ["crisprFileDropzone"], outputs: ["fileDrop"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
706
- }
707
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FileUploadFieldComponent, decorators: [{
708
- type: Component,
709
- args: [{ selector: 'crispr-file-upload-field', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
710
- CommonModule,
711
- FieldContainerComponent,
712
- ReactiveFormsModule,
713
- MatIconModule,
714
- MatButtonModule,
715
- MatFormFieldModule,
716
- MatInputModule,
717
- SelectedFileComponent,
718
- FormValidationHandlerModule,
719
- FileDropzoneDirective,
720
- ], standalone: true, template: "<crispr-field-container\n [config]=\"config()\"\n [group]=\"group()\">\n <mat-form-field floatLabel=\"always\"\n [attr.data-testid]=\"testId()\"\n [color]=\"config().color\"\n appearance=\"outline\"\n [crisprFileDropzone]=\"!(disabled$ | async) && !(config().disableOnUpload && uploaded())\"\n [formGroup]=\"group()\"\n (fileDrop)=\"filesChanged($event)\">\n\n <input [formControlName]=\"config().controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n style=\"display: none\"\n [accept]=\"config().acceptedTypes\"\n [multiple]=\"config().allowMultipleFiles\"\n (change)=\"filesChanged($event.target.files)\"/>\n <mat-label>{{config().label}}</mat-label>\n\n @if (!selectedFiles() || selectedFiles().length === 0) {\n <div class=\"drop-info\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config().dropZoneText}}</h2>\n or\n <button\n mat-raised-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async) || config().disableOnUpload && uploaded()\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config().controlName\">\n {{config().selectButtonText}}\n </button>\n </div>\n } @else {\n <div class=\"selected-files-container\">\n <div class=\"selected-files-list\">\n @for (file of selectedFilesArray(); track file; let i = $index) {\n <crispr-selected-file\n [color]=\"config().color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"file.name\"\n [showProgress]=\"config().showUploadProgress\"\n [progress]=\"fileProgress && (fileProgress[i] | async)\">\n </crispr-selected-file>\n }\n </div>\n </div>\n }\n @if (config().hint && (control().valid || !control().touched)) {<mat-hint>{{config().hint}}</mat-hint>}\n </mat-form-field>\n @if ((selectedFiles())?.length > 0) {\n <div class=\"button-container\">\n <button\n mat-button\n (click)=\"resetFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async) || (config().disableOnUpload && uploaded())\"\n aria-label=\"Remove Selected File(s)\">\n {{config().clearFilesButtonText}}\n <mat-icon>delete</mat-icon>\n </button>\n @if (!!config().uploadFiles) {\n <button\n mat-raised-button\n type=\"button\"\n color=\"accent\"\n class=\"file-input-button\"\n [disabled]=\"(disabled$ | async) || (config().disableOnUpload && uploaded())\"\n (click)=\"uploadFiles()\"\n [attr.aria-label]=\"config().uploadButtonText\">\n {{ config().uploadButtonText }}\n </button>\n }\n </div>\n }\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-mdc-form-field .mat-mdc-form-field-infix{padding-top:0;display:flex;justify-content:center}:host .drop-info{display:flex;flex-direction:column;align-items:center}:host .drop-info .drop-icon{font-size:36px}:host .drop-info .mat-h2{margin:0}:host .button-container{display:flex;justify-content:flex-end;margin-top:-16px}:host .button-container button{margin-left:8px}:host .selected-files-container{width:100%}:host [matInput]{position:absolute;max-height:0;visibility:hidden}\n"] }]
721
- }], ctorParameters: () => [], propDecorators: { fileInputRef: [{
722
- type: ViewChild,
723
- args: ['fileInput']
724
- }] } });
725
-
726
- var index$3 = /*#__PURE__*/Object.freeze({
727
- __proto__: null,
728
- FileUploadFieldComponent: FileUploadFieldComponent
729
- });
730
-
731
- var index$2 = /*#__PURE__*/Object.freeze({
732
- __proto__: null,
733
- FieldContainerComponent: FieldContainerComponent,
734
- FileDropzoneDirective: FileDropzoneDirective,
735
- FileUploadFieldComponent: FileUploadFieldComponent,
736
- HeadingComponent: HeadingComponent,
737
- InfoComponent: InfoComponent,
738
- SelectedFileComponent: SelectedFileComponent
739
- });
740
-
741
- class CrisprDisplayFieldDirective {
742
- constructor() {
743
- this.container = inject(ViewContainerRef);
744
- this.group = input(...(ngDevMode ? [undefined, { debugName: "group" }] : []));
745
- this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
746
- this.component = input(...(ngDevMode ? [undefined, { debugName: "component" }] : []));
747
- this.index = input(...(ngDevMode ? [undefined, { debugName: "index" }] : []));
748
- effect(() => {
749
- this.updateComponentValue(this.value());
750
- });
751
- }
752
- async ngOnInit() {
753
- if (this.component()) {
754
- const componentRef = this.container.createComponent(this.component());
755
- this.componentRef = componentRef;
756
- this.componentInstance = componentRef.instance;
757
- this.componentInstance.index = this.index();
758
- this.updateComponentValue(this.value());
759
- }
760
- }
761
- updateComponentValue(value) {
762
- if (!this.componentRef)
763
- return;
764
- this.componentRef.setInput('value', value);
765
- }
766
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprDisplayFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
767
- 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 }); }
768
- }
769
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprDisplayFieldDirective, decorators: [{
770
- type: Directive,
771
- args: [{
772
- selector: '[crisprDisplayField]',
773
- standalone: true,
774
- }]
775
- }], 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 }] }] } });
776
-
777
- const defaultConfig = {
778
- addButtonLabel: 'ADD ITEM',
779
- minListLength: 1,
780
- };
781
- class FormGroupListComponent extends CrisprControlComponent {
782
- constructor() {
783
- super(...arguments);
784
- this.defaultConfig = defaultConfig;
785
- /**
786
- * By setting this to true when adding/removing items from array,
787
- * we can block original values from overwriting form values
788
- * */
789
- this.blockValue = false;
790
- this.selectedIndex = null;
791
- }
792
- ngOnInit() {
793
- super.ngOnInit();
794
- // TODO: this is required to ngFor of controls in template, must be a better way
795
- }
796
- setControlValue(values) {
797
- const formArray = this.control();
798
- if (formArray) {
799
- if (values?.length > 0) {
800
- // clear any existing values so that new values don't concatenate onto the old
801
- const currentValues = formArray.value;
802
- if (currentValues.length) {
803
- formArray.clear();
804
- }
805
- values.forEach((value) => this.addGroup(value));
806
- }
807
- else if (this.config().displayInitialItem) {
808
- this.addGroup();
809
- }
810
- }
811
- }
812
- clickDelete(index) {
813
- this.blockValue = true;
814
- this.deleteGroup(index);
815
- }
816
- clickAdd() {
817
- this.blockValue = true;
818
- this.addGroup();
819
- }
820
- addGroup(value = null) {
821
- const formArray = this.control();
822
- formArray.push(createControlForType(this.config().itemConfig, value));
823
- }
824
- deleteGroup(index) {
825
- const formArray = this.control();
826
- formArray.removeAt(index);
827
- }
828
- clickEditItem(index) {
829
- this.selectedIndex = index;
830
- }
831
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FormGroupListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
832
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: FormGroupListComponent, isStandalone: true, selector: "crispr-form-group-list", usesInheritance: true, ngImport: i0, template: "<crispr-field-container [config]=\"config()\" [group]=\"group()\" [formGroup]=\"group()\">\n\n <div [formArrayName]=\"config().controlName\">\n\n <!-- Don't add trackBy function, it confuses the state of the array -->\n @for (itemControl of control()?.controls; track itemControl; let i = $index; let last = $last) {\n @if (!config().displayItemComponent || i === selectedIndex || (last && selectedIndex ?? true)) {\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config().itemLabelBuilder ? config().itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n @if (i + 1 > config().minListLength) {\n <button mat-icon-button type=\"button\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n }\n </div>\n <div [formGroup]=\"itemControl\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n @for (field of config().itemConfig.fields; track field) {\n <ng-container crisprField [value]=\"blockValue ? null : value()?.[i] | initialControlValue : field\"\n [config]=\"field\" [group]=\"itemControl\" [testIdPrefix]=\"testId() + '[' + i + ']'\">\n </ng-container>\n }\n </div>\n } @else {\n <div class=\"display-field-container\" crisprDisplayField [component]=\"config().displayItemComponent\"\n [value]=\"itemControl.value\" [index]=\"i\">\n <button mat-icon-button (click)=\"clickEditItem(i)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n }\n <ng-template #display>\n <div class=\"display-field-container\" crisprDisplayField [component]=\"config().displayItemComponent\"\n [value]=\"itemControl.value\" [index]=\"i\">\n <button mat-icon-button (click)=\"clickEditItem(i)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n </ng-template>\n }\n </div>\n <div class=\"group-footer\">\n <button type=\"button\" class=\"add\" mat-raised-button [color]=\"config().addButtonColor\" (click)=\"clickAdd()\">\n {{config().addItemLabel || config().addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}.display-field-container{position:relative}.display-field-container button{position:absolute;top:0;right:0}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1$3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { 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: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "testIdPrefix", "value"] }, { kind: "directive", type: CrisprDisplayFieldDirective, selector: "[crisprDisplayField]", inputs: ["group", "value", "component", "index"] }, { kind: "ngmodule", type: CrisprPipesModule }, { kind: "ngmodule", type: FormValidationHandlerModule }, { kind: "directive", type: i6.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true }); }
833
- }
834
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: FormGroupListComponent, decorators: [{
835
- type: Component,
836
- args: [{ selector: 'crispr-form-group-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
837
- MatButtonModule,
838
- MatIconModule,
839
- FieldContainerComponent,
840
- ReactiveFormsModule,
841
- CrisprFieldDirective,
842
- CrisprDisplayFieldDirective,
843
- CrisprPipesModule,
844
- FormValidationHandlerModule
845
- ], standalone: true, template: "<crispr-field-container [config]=\"config()\" [group]=\"group()\" [formGroup]=\"group()\">\n\n <div [formArrayName]=\"config().controlName\">\n\n <!-- Don't add trackBy function, it confuses the state of the array -->\n @for (itemControl of control()?.controls; track itemControl; let i = $index; let last = $last) {\n @if (!config().displayItemComponent || i === selectedIndex || (last && selectedIndex ?? true)) {\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config().itemLabelBuilder ? config().itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n @if (i + 1 > config().minListLength) {\n <button mat-icon-button type=\"button\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n }\n </div>\n <div [formGroup]=\"itemControl\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n @for (field of config().itemConfig.fields; track field) {\n <ng-container crisprField [value]=\"blockValue ? null : value()?.[i] | initialControlValue : field\"\n [config]=\"field\" [group]=\"itemControl\" [testIdPrefix]=\"testId() + '[' + i + ']'\">\n </ng-container>\n }\n </div>\n } @else {\n <div class=\"display-field-container\" crisprDisplayField [component]=\"config().displayItemComponent\"\n [value]=\"itemControl.value\" [index]=\"i\">\n <button mat-icon-button (click)=\"clickEditItem(i)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n }\n <ng-template #display>\n <div class=\"display-field-container\" crisprDisplayField [component]=\"config().displayItemComponent\"\n [value]=\"itemControl.value\" [index]=\"i\">\n <button mat-icon-button (click)=\"clickEditItem(i)\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n </ng-template>\n }\n </div>\n <div class=\"group-footer\">\n <button type=\"button\" class=\"add\" mat-raised-button [color]=\"config().addButtonColor\" (click)=\"clickAdd()\">\n {{config().addItemLabel || config().addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}.display-field-container{position:relative}.display-field-container button{position:absolute;top:0;right:0}\n"] }]
846
- }] });
847
-
848
- var index$1 = /*#__PURE__*/Object.freeze({
849
- __proto__: null,
850
- FormGroupListComponent: FormGroupListComponent
851
- });
852
-
853
- class SubGroupComponent extends CrisprControlComponent {
854
- ngOnInit() {
855
- super.ngOnInit();
856
- }
857
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
858
- 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 }); }
859
- }
860
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupComponent, decorators: [{
861
- type: Component,
862
- args: [{ selector: 'crispr-sub-group', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
863
- CommonModule,
864
- ReactiveFormsModule,
865
- CrisprFieldDirective,
866
- FieldContainerComponent,
867
- CrisprPipesModule,
868
- FormValidationHandlerModule,
869
- ], 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>" }]
870
- }] });
871
-
872
- /**
873
- * @deprecated SubGroupComponent is now standalone. Import SubGroupComponent directly.
874
- * This module will be removed in the next major version.
875
- */
876
- class SubGroupModule {
877
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
878
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, imports: [SubGroupComponent], exports: [SubGroupComponent] }); }
879
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, imports: [SubGroupComponent] }); }
880
- }
881
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SubGroupModule, decorators: [{
882
- type: NgModule,
883
- args: [{
884
- imports: [SubGroupComponent],
885
- exports: [SubGroupComponent],
886
- }]
887
- }] });
888
-
889
- var index = /*#__PURE__*/Object.freeze({
890
- __proto__: null,
891
- SubGroupComponent: SubGroupComponent,
892
- SubGroupModule: SubGroupModule
893
- });
894
-
895
- /**
896
- * @deprecated Use stanadlone CripsrFormComponent
897
- */
898
- class CrisprFormsModule {
899
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
900
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, imports: [CommonModule,
901
- ReactiveFormsModule,
902
- FormValidationHandlerModule,
903
- FormGroupListComponent,
904
- FieldContainerComponent,
905
- CrisprFieldDirective,
906
- CrisprDisplayFieldDirective,
907
- SubGroupModule,
908
- CrisprPipesModule,
909
- CrisprFormComponent], exports: [CrisprFormComponent, FieldContainerComponent] }); }
910
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, imports: [CommonModule,
911
- ReactiveFormsModule,
912
- FormValidationHandlerModule,
913
- FormGroupListComponent,
914
- FieldContainerComponent,
915
- SubGroupModule,
916
- CrisprPipesModule,
917
- CrisprFormComponent] }); }
918
- }
919
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: CrisprFormsModule, decorators: [{
920
- type: NgModule,
921
- args: [{
922
- imports: [
923
- CommonModule,
924
- ReactiveFormsModule,
925
- FormValidationHandlerModule,
926
- FormGroupListComponent,
927
- FieldContainerComponent,
928
- CrisprFieldDirective,
929
- CrisprDisplayFieldDirective,
930
- SubGroupModule,
931
- CrisprPipesModule,
932
- CrisprFormComponent,
933
- ],
934
- exports: [CrisprFormComponent, FieldContainerComponent],
935
- }]
936
- }] });
937
-
938
- /**
939
- * Generated bundle index. Do not edit.
940
- */
941
-
942
- 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 };
943
- //# sourceMappingURL=tft-crispr-forms-tft-crispr-forms-8liD7eof.mjs.map