@mosaicoo/form-angular 0.4.0 → 0.6.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.
@@ -1,6 +1,6 @@
1
- import { NgComponentOutlet, DOCUMENT } from '@angular/common';
1
+ import { NgComponentOutlet, NgTemplateOutlet, DOCUMENT } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { InjectionToken, makeEnvironmentProviders, input, signal, inject, ChangeDetectorRef, effect, untracked, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, output } from '@angular/core';
3
+ import { InjectionToken, makeEnvironmentProviders, input, signal, inject, ChangeDetectorRef, reflectComponentType, effect, untracked, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, output } from '@angular/core';
4
4
  import { maskValue, importForm, createLegacyImporter, createFormEngine, collectInputs } from '@mosaicoo/form-core';
5
5
 
6
6
  /** Multi-provider token: maps merge, later providers win on conflicts. */
@@ -40,6 +40,13 @@ function provideMosaicooForm(config) {
40
40
  return makeEnvironmentProviders(providers);
41
41
  }
42
42
 
43
+ function formatBytes(bytes) {
44
+ if (bytes >= 1024 * 1024)
45
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
46
+ if (bytes >= 1024)
47
+ return `${Math.round(bytes / 1024)} KB`;
48
+ return `${bytes} B`;
49
+ }
43
50
  /**
44
51
  * Renders one schema node (input, container or static) and recurses into
45
52
  * children. State lives in the headless engine — this component only projects
@@ -99,14 +106,22 @@ class FormNodeComponent {
99
106
  }
100
107
  return null;
101
108
  }
102
- /** Inputs handed to a custom component (MformFieldComponent contract). */
109
+ /**
110
+ * Inputs handed to a custom component (MformFieldComponent contract).
111
+ * Only inputs the component actually declares are passed, so optional
112
+ * contract members (`mode`) never break third-party components.
113
+ */
103
114
  customInputs() {
104
- return {
115
+ const component = this.customComponent();
116
+ const declared = new Set(component ? (reflectComponentType(component)?.inputs ?? []).map((i) => i.propName) : []);
117
+ const all = {
105
118
  field: this.field(),
106
119
  engine: this.engine(),
107
120
  path: this.path(),
108
121
  tick: this.tick(),
122
+ mode: this.mode(),
109
123
  };
124
+ return Object.fromEntries(Object.entries(all).filter(([key]) => declared.has(key)));
110
125
  }
111
126
  /** Options resolved from a dynamic source (provider or remote URL). */
112
127
  resolvedOptions = signal(null, ...(ngDevMode ? [{ debugName: "resolvedOptions" }] : /* istanbul ignore next */ []));
@@ -332,7 +347,19 @@ class FormNodeComponent {
332
347
  }
333
348
  }
334
349
  setSelect(event) {
335
- this.setValue(event.target.value);
350
+ const select = event.target;
351
+ if (this.field().multiple) {
352
+ this.setValue(Array.from(select.selectedOptions, (option) => option.value));
353
+ return;
354
+ }
355
+ this.setValue(select.value);
356
+ }
357
+ /** Selection state for single and multi-value choice fields. */
358
+ isSelected(optionValue) {
359
+ const value = this.value();
360
+ if (Array.isArray(value))
361
+ return value.some((item) => `${item}` === `${optionValue}`);
362
+ return this.stringValue() === `${optionValue}`;
336
363
  }
337
364
  setChecked(event) {
338
365
  this.setValue(event.target.checked);
@@ -341,19 +368,48 @@ class FormNodeComponent {
341
368
  const checked = event.target.checked;
342
369
  this.setValue({ ...this.mapValue(), [option]: checked });
343
370
  }
371
+ /** Client-side rejection message (size/type), cleared on the next pick. */
372
+ fileRejection = signal(null, ...(ngDevMode ? [{ debugName: "fileRejection" }] : /* istanbul ignore next */ []));
373
+ acceptAttr() {
374
+ const accept = this.field().files?.accept;
375
+ if (accept)
376
+ return accept;
377
+ return this.field().type === 'image' ? 'image/*' : null;
378
+ }
344
379
  setFiles(event) {
345
- const files = event.target.files;
346
- const list = files ? Array.from(files) : [];
347
- if (!this.uploader || list.length === 0) {
380
+ const input = event.target;
381
+ const picked = input.files ? Array.from(input.files) : [];
382
+ this.fileRejection.set(null);
383
+ if (picked.length === 0)
384
+ return;
385
+ // Client-side guards give immediate feedback; the back end stays the
386
+ // authoritative check (file COUNT is a real rule via maxLength).
387
+ const maxSize = this.field().files?.maxSize;
388
+ const tooBig = maxSize ? picked.filter((file) => file.size > maxSize) : [];
389
+ const list = maxSize ? picked.filter((file) => file.size <= maxSize) : picked;
390
+ if (tooBig.length > 0) {
391
+ this.fileRejection.set(`${tooBig.map((f) => f.name).join(', ')} — above ${formatBytes(maxSize)}`);
392
+ }
393
+ if (list.length === 0) {
394
+ input.value = '';
395
+ return;
396
+ }
397
+ const previous = this.fileEntries();
398
+ const append = this.field().multiple !== false;
399
+ if (!this.uploader) {
348
400
  // no host uploader: only file names are stored
349
- this.setValue(list.map((f) => f.name));
401
+ const names = list.map((f) => f.name);
402
+ this.setValue(append ? [...previous.map((e) => e.name), ...names] : names);
350
403
  return;
351
404
  }
352
405
  const field = this.field();
353
406
  const path = this.path();
354
407
  this.uploading.set(true);
355
408
  Promise.all(list.map((file) => this.uploader(file, { field, path })))
356
- .then((refs) => this.setValue(refs))
409
+ .then((refs) => {
410
+ const current = append ? this.value() ?? [] : [];
411
+ this.setValue([...current, ...refs]);
412
+ })
357
413
  .catch(() => { }) // host upload failure keeps the previous value
358
414
  .finally(() => {
359
415
  this.uploading.set(false);
@@ -361,14 +417,37 @@ class FormNodeComponent {
361
417
  this.notify()();
362
418
  });
363
419
  }
364
- /** Names shown under a `file` control (refs or plain names). */
365
- fileNames() {
420
+ /** Normalized view of the stored value: name + optional preview url. */
421
+ fileEntries() {
366
422
  const value = this.value();
367
423
  if (!Array.isArray(value))
368
424
  return [];
369
- return value.map((item) => typeof item === 'object' && item !== null
370
- ? String(item.name ?? '')
371
- : String(item));
425
+ return value.map((item) => {
426
+ if (typeof item === 'object' && item !== null) {
427
+ const ref = item;
428
+ return {
429
+ name: String(ref.name ?? ''),
430
+ url: typeof ref.url === 'string' ? ref.url : null,
431
+ };
432
+ }
433
+ const name = String(item);
434
+ // A bare string that already looks like a URL doubles as the preview.
435
+ return { name, url: /^(https?:|data:image\/|blob:)/.test(name) ? name : null };
436
+ });
437
+ }
438
+ showThumbnails() {
439
+ const field = this.field();
440
+ if (field.files?.preview === false)
441
+ return false;
442
+ return field.type === 'image' || field.files?.preview === true;
443
+ }
444
+ removeFile(index) {
445
+ const value = this.value();
446
+ if (!Array.isArray(value))
447
+ return;
448
+ const next = [...value];
449
+ next.splice(index, 1);
450
+ this.setValue(next);
372
451
  }
373
452
  prefix() {
374
453
  const value = this.node().props?.['prefix'];
@@ -617,17 +696,21 @@ class FormNodeComponent {
617
696
  class="mform-control"
618
697
  [id]="controlId()"
619
698
  [disabled]="controlDisabled()"
699
+ [multiple]="field().multiple === true"
700
+ [attr.size]="field().multiple ? 5 : null"
620
701
  [attr.aria-required]="required() || null"
621
702
  [attr.aria-invalid]="errors().length > 0 || null"
622
703
  [attr.aria-describedby]="describedBy()"
623
704
  (change)="setSelect($event)"
624
705
  (blur)="touch()"
625
706
  >
626
- <option value="" [selected]="stringValue() === ''"></option>
707
+ @if (!field().multiple) {
708
+ <option value="" [selected]="stringValue() === ''"></option>
709
+ }
627
710
  @for (option of options(); track option.value) {
628
711
  <option
629
712
  [value]="option.value"
630
- [selected]="stringValue() === '' + option.value"
713
+ [selected]="isSelected(option.value)"
631
714
  >
632
715
  {{ option.label }}
633
716
  </option>
@@ -712,23 +795,10 @@ class FormNodeComponent {
712
795
  </div>
713
796
  }
714
797
  @case ('file') {
715
- <input
716
- class="mform-control"
717
- type="file"
718
- multiple
719
- [id]="controlId()"
720
- [disabled]="controlDisabled() || uploading()"
721
- [attr.aria-busy]="uploading() || null"
722
- [attr.aria-describedby]="describedBy()"
723
- (change)="setFiles($event)"
724
- (blur)="touch()"
725
- />
726
- @if (uploading()) {
727
- <div class="mform-desc" role="status">Uploading…</div>
728
- }
729
- @for (name of fileNames(); track $index) {
730
- <div class="mform-file-name">📎 {{ name }}</div>
731
- }
798
+ <ng-container *ngTemplateOutlet="fileControl" />
799
+ }
800
+ @case ('image') {
801
+ <ng-container *ngTemplateOutlet="fileControl" />
732
802
  }
733
803
  @case ('reference') {
734
804
  <div class="mform-reference">
@@ -803,7 +873,52 @@ class FormNodeComponent {
803
873
  }
804
874
  }
805
875
  }
806
- `, isInline: true, dependencies: [{ kind: "component", type: FormNodeComponent, selector: "mform-node", inputs: ["node", "engine", "tick", "scope", "bare", "providers", "mode", "notify"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
876
+
877
+ <!-- File/image control: same markup for both types, thumbnails when the
878
+ stored reference points at an image. -->
879
+ <ng-template #fileControl>
880
+ <input
881
+ class="mform-control"
882
+ type="file"
883
+ [id]="controlId()"
884
+ [multiple]="field().multiple !== false"
885
+ [attr.accept]="acceptAttr()"
886
+ [disabled]="controlDisabled() || uploading()"
887
+ [attr.aria-busy]="uploading() || null"
888
+ [attr.aria-describedby]="describedBy()"
889
+ (change)="setFiles($event)"
890
+ (blur)="touch()"
891
+ />
892
+ @if (uploading()) {
893
+ <div class="mform-desc" role="status">Uploading…</div>
894
+ }
895
+ @if (fileRejection(); as rejection) {
896
+ <div class="mform-error" role="alert">{{ rejection }}</div>
897
+ }
898
+ @if (fileEntries().length > 0) {
899
+ <ul class="mform-files" [class.is-gallery]="showThumbnails()">
900
+ @for (entry of fileEntries(); track $index; let i = $index) {
901
+ <li class="mform-file">
902
+ @if (showThumbnails() && entry.url) {
903
+ <img class="mform-thumb" [src]="entry.url" [alt]="entry.name" loading="lazy" />
904
+ } @else {
905
+ <span class="mform-file-icon" aria-hidden="true">📎</span>
906
+ }
907
+ <span class="mform-file-name" [title]="entry.name">{{ entry.name }}</span>
908
+ @if (interactive()) {
909
+ <button
910
+ type="button"
911
+ class="mform-file-remove"
912
+ (click)="removeFile(i)"
913
+ [attr.aria-label]="'Remove ' + entry.name"
914
+ >✕</button>
915
+ }
916
+ </li>
917
+ }
918
+ </ul>
919
+ }
920
+ </ng-template>
921
+ `, isInline: true, dependencies: [{ kind: "component", type: FormNodeComponent, selector: "mform-node", inputs: ["node", "engine", "tick", "scope", "bare", "providers", "mode", "notify"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
807
922
  }
808
923
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FormNodeComponent, decorators: [{
809
924
  type: Component,
@@ -812,7 +927,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
812
927
  changeDetection: ChangeDetectionStrategy.OnPush,
813
928
  encapsulation: ViewEncapsulation.None,
814
929
  host: { class: 'mform-node' },
815
- imports: [NgComponentOutlet],
930
+ imports: [NgComponentOutlet, NgTemplateOutlet],
816
931
  template: `
817
932
  @let n = node();
818
933
  @if (visible()) {
@@ -961,17 +1076,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
961
1076
  class="mform-control"
962
1077
  [id]="controlId()"
963
1078
  [disabled]="controlDisabled()"
1079
+ [multiple]="field().multiple === true"
1080
+ [attr.size]="field().multiple ? 5 : null"
964
1081
  [attr.aria-required]="required() || null"
965
1082
  [attr.aria-invalid]="errors().length > 0 || null"
966
1083
  [attr.aria-describedby]="describedBy()"
967
1084
  (change)="setSelect($event)"
968
1085
  (blur)="touch()"
969
1086
  >
970
- <option value="" [selected]="stringValue() === ''"></option>
1087
+ @if (!field().multiple) {
1088
+ <option value="" [selected]="stringValue() === ''"></option>
1089
+ }
971
1090
  @for (option of options(); track option.value) {
972
1091
  <option
973
1092
  [value]="option.value"
974
- [selected]="stringValue() === '' + option.value"
1093
+ [selected]="isSelected(option.value)"
975
1094
  >
976
1095
  {{ option.label }}
977
1096
  </option>
@@ -1056,23 +1175,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1056
1175
  </div>
1057
1176
  }
1058
1177
  @case ('file') {
1059
- <input
1060
- class="mform-control"
1061
- type="file"
1062
- multiple
1063
- [id]="controlId()"
1064
- [disabled]="controlDisabled() || uploading()"
1065
- [attr.aria-busy]="uploading() || null"
1066
- [attr.aria-describedby]="describedBy()"
1067
- (change)="setFiles($event)"
1068
- (blur)="touch()"
1069
- />
1070
- @if (uploading()) {
1071
- <div class="mform-desc" role="status">Uploading…</div>
1072
- }
1073
- @for (name of fileNames(); track $index) {
1074
- <div class="mform-file-name">📎 {{ name }}</div>
1075
- }
1178
+ <ng-container *ngTemplateOutlet="fileControl" />
1179
+ }
1180
+ @case ('image') {
1181
+ <ng-container *ngTemplateOutlet="fileControl" />
1076
1182
  }
1077
1183
  @case ('reference') {
1078
1184
  <div class="mform-reference">
@@ -1147,6 +1253,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1147
1253
  }
1148
1254
  }
1149
1255
  }
1256
+
1257
+ <!-- File/image control: same markup for both types, thumbnails when the
1258
+ stored reference points at an image. -->
1259
+ <ng-template #fileControl>
1260
+ <input
1261
+ class="mform-control"
1262
+ type="file"
1263
+ [id]="controlId()"
1264
+ [multiple]="field().multiple !== false"
1265
+ [attr.accept]="acceptAttr()"
1266
+ [disabled]="controlDisabled() || uploading()"
1267
+ [attr.aria-busy]="uploading() || null"
1268
+ [attr.aria-describedby]="describedBy()"
1269
+ (change)="setFiles($event)"
1270
+ (blur)="touch()"
1271
+ />
1272
+ @if (uploading()) {
1273
+ <div class="mform-desc" role="status">Uploading…</div>
1274
+ }
1275
+ @if (fileRejection(); as rejection) {
1276
+ <div class="mform-error" role="alert">{{ rejection }}</div>
1277
+ }
1278
+ @if (fileEntries().length > 0) {
1279
+ <ul class="mform-files" [class.is-gallery]="showThumbnails()">
1280
+ @for (entry of fileEntries(); track $index; let i = $index) {
1281
+ <li class="mform-file">
1282
+ @if (showThumbnails() && entry.url) {
1283
+ <img class="mform-thumb" [src]="entry.url" [alt]="entry.name" loading="lazy" />
1284
+ } @else {
1285
+ <span class="mform-file-icon" aria-hidden="true">📎</span>
1286
+ }
1287
+ <span class="mform-file-name" [title]="entry.name">{{ entry.name }}</span>
1288
+ @if (interactive()) {
1289
+ <button
1290
+ type="button"
1291
+ class="mform-file-remove"
1292
+ (click)="removeFile(i)"
1293
+ [attr.aria-label]="'Remove ' + entry.name"
1294
+ >✕</button>
1295
+ }
1296
+ </li>
1297
+ }
1298
+ </ul>
1299
+ }
1300
+ </ng-template>
1150
1301
  `,
1151
1302
  }]
1152
1303
  }], ctorParameters: () => [], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }], engine: [{ type: i0.Input, args: [{ isSignal: true, alias: "engine", required: true }] }], tick: [{ type: i0.Input, args: [{ isSignal: true, alias: "tick", required: true }] }], scope: [{ type: i0.Input, args: [{ isSignal: true, alias: "scope", required: false }] }], bare: [{ type: i0.Input, args: [{ isSignal: true, alias: "bare", required: false }] }], providers: [{ type: i0.Input, args: [{ isSignal: true, alias: "providers", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], notify: [{ type: i0.Input, args: [{ isSignal: true, alias: "notify", required: false }] }] } });
@@ -1404,7 +1555,7 @@ class FormRendererComponent {
1404
1555
  }
1405
1556
  </form>
1406
1557
  }
1407
- `, isInline: true, styles: [".mform-root{display:flex;flex-direction:column;gap:var(--mform-gap, 16px);font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e)}.mform-node{display:contents}.mform-field{display:flex;flex-direction:column;gap:6px}.mform-label{font-size:var(--mform-label-size, 13px);font-weight:var(--mform-label-weight, 600)}.mform-req{color:var(--mform-danger, #c62842);margin-left:2px}.mform-control{font:inherit;width:100%;padding:var(--mform-control-padding, 9px 12px);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff);color:inherit;box-sizing:border-box}textarea.mform-control{min-height:72px;resize:vertical}.mform-control:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px;border-color:var(--mform-focus, #8e6ff0)}.mform-field.has-error .mform-control{border-color:var(--mform-danger, #c62842)}.mform-desc{font-size:12px;color:var(--mform-muted, #6b6580)}.mform-error{font-size:12px;color:var(--mform-danger, #c62842)}.mform-choices{display:flex;flex-direction:column;gap:6px}.mform-check{display:flex;align-items:center;gap:8px;font-size:14px;cursor:pointer}.mform-check input{width:16px;height:16px;accent-color:var(--mform-primary, #6d4bd0)}.mform-panel{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.mform-panel-head{background:var(--mform-panel-head-bg, linear-gradient(90deg, #efeaff, #f8f6ff));color:var(--mform-panel-head-text, inherit);padding:10px 16px;font-weight:600;font-size:14px;border-bottom:1px solid var(--mform-border, #d9d5e6)}.mform-panel-body,.mform-group,.mform-column,.mform-tabpanel{display:flex;flex-direction:column;gap:var(--mform-gap, 16px)}.mform-panel-body{padding:var(--mform-panel-padding, 16px)}.mform-columns{display:grid;gap:var(--mform-gap, 16px)}@media(max-width:640px){.mform-columns{grid-template-columns:1fr!important}}.mform-affix{display:flex;align-items:center}.mform-affix.has-affix{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff)}.mform-affix.has-affix .mform-control{border:none;background:none;flex:1}.mform-affix.has-affix:focus-within{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px}.mform-prefix,.mform-suffix{padding:0 10px;color:var(--mform-muted, #6b6580);font-size:13px;white-space:nowrap}.mform-tags{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.mform-tag{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-radius:999px;padding:3px 10px;font-size:12px;display:inline-flex;align-items:center;gap:6px}.mform-tag button{border:none;background:none;color:inherit;cursor:pointer;font-size:12px;padding:0;line-height:1}.mform-tag-input{flex:1;min-width:140px;width:auto}.mform-field.is-pending .mform-control{background-image:linear-gradient(90deg,transparent 0%,rgb(109 75 208 / 12%) 50%,transparent 100%);background-size:200% 100%;animation:mform-pending 1.2s linear infinite}@keyframes mform-pending{0%{background-position:200% 0}to{background-position:-200% 0}}.mform-file-name{font-size:12px;color:var(--mform-muted, #6b6580);padding:2px 0}.mform-reference{position:relative}.mform-ref-list{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:10;margin:0;padding:4px;list-style:none;background:var(--mform-control-bg, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);box-shadow:0 8px 24px #1f1b2e1f;max-height:220px;overflow-y:auto}.mform-ref-list button{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:7px 10px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.mform-ref-list button:hover{background:var(--mform-bg, #f6f5fa)}.mform-tabbar{display:flex;gap:4px;border-bottom:2px solid var(--mform-border, #d9d5e6);margin-bottom:14px}.mform-tab{padding:8px 18px;font:inherit;font-size:14px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.mform-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.mform-grid-row{display:flex;align-items:flex-start;gap:8px;padding:10px 0;border-bottom:1px dashed var(--mform-border, #d9d5e6)}.mform-grid-fields{flex:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--mform-gap, 16px)}.mform-row-remove{border:none;background:none;color:var(--mform-muted, #6b6580);font:inherit;cursor:pointer;padding:6px 8px}.mform-row-remove:hover{color:var(--mform-danger, #c62842)}.mform-row-add{align-self:flex-start;background:none;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);padding:7px 14px;border-radius:var(--mform-control-radius, 8px);font:inherit;font-size:13px;cursor:pointer}.mform-btn{align-self:flex-start;background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border:none;border-radius:var(--mform-control-radius, 8px);padding:11px 26px;font:inherit;font-weight:600;cursor:pointer}.mform-btn:hover{filter:brightness(1.08)}.mform-btn:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:2px}.mform-content{font-size:14px}.mform-unsupported{font-size:13px;color:var(--mform-muted, #6b6580);border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:10px 14px}.mform-steps{display:flex;gap:18px;list-style:none;margin:0 0 4px;padding:0 0 12px;border-bottom:1px solid var(--mform-border, #d9d5e6);flex-wrap:wrap}.mform-step{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--mform-muted, #6b6580)}.mform-step-index{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;border:1.5px solid var(--mform-border, #d9d5e6);font-size:11px;font-weight:600}.mform-step.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600}.mform-step.is-active .mform-step-index{border-color:var(--mform-primary, #6d4bd0);background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.mform-step.is-done .mform-step-index{border-color:var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-wizard-nav{display:flex;gap:10px;padding-top:4px}.mform-btn-secondary{background:none;border:1px solid var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-summary{border:1px solid var(--mform-danger, #c62842);background:var(--mform-danger-bg, #fdf0f2);color:var(--mform-danger, #c62842);border-radius:var(--mform-radius, 10px);padding:12px 16px;font-size:13px}.mform-summary ul{margin:6px 0 0;padding-left:18px}\n"], dependencies: [{ kind: "component", type: FormNodeComponent, selector: "mform-node", inputs: ["node", "engine", "tick", "scope", "bare", "providers", "mode", "notify"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1558
+ `, isInline: true, styles: [".mform-root{display:flex;flex-direction:column;gap:var(--mform-gap, 16px);font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e)}.mform-node{display:contents}.mform-field{display:flex;flex-direction:column;gap:6px}.mform-label{font-size:var(--mform-label-size, 13px);font-weight:var(--mform-label-weight, 600)}.mform-req{color:var(--mform-danger, #c62842);margin-left:2px}.mform-control{font:inherit;width:100%;padding:var(--mform-control-padding, 9px 12px);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff);color:inherit;box-sizing:border-box}textarea.mform-control{min-height:72px;resize:vertical}.mform-control:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px;border-color:var(--mform-focus, #8e6ff0)}.mform-field.has-error .mform-control{border-color:var(--mform-danger, #c62842)}.mform-desc{font-size:12px;color:var(--mform-muted, #6b6580)}.mform-error{font-size:12px;color:var(--mform-danger, #c62842)}.mform-choices{display:flex;flex-direction:column;gap:6px}.mform-check{display:flex;align-items:center;gap:8px;font-size:14px;cursor:pointer}.mform-check input{width:16px;height:16px;accent-color:var(--mform-primary, #6d4bd0)}.mform-panel{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.mform-panel-head{background:var(--mform-panel-head-bg, linear-gradient(90deg, #efeaff, #f8f6ff));color:var(--mform-panel-head-text, inherit);padding:10px 16px;font-weight:600;font-size:14px;border-bottom:1px solid var(--mform-border, #d9d5e6)}.mform-panel-body,.mform-group,.mform-column,.mform-tabpanel{display:flex;flex-direction:column;gap:var(--mform-gap, 16px)}.mform-panel-body{padding:var(--mform-panel-padding, 16px)}.mform-columns{display:grid;gap:var(--mform-gap, 16px)}@media(max-width:640px){.mform-columns{grid-template-columns:1fr!important}}.mform-affix{display:flex;align-items:center}.mform-affix.has-affix{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff)}.mform-affix.has-affix .mform-control{border:none;background:none;flex:1}.mform-affix.has-affix:focus-within{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px}.mform-prefix,.mform-suffix{padding:0 10px;color:var(--mform-muted, #6b6580);font-size:13px;white-space:nowrap}.mform-tags{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.mform-tag{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-radius:999px;padding:3px 10px;font-size:12px;display:inline-flex;align-items:center;gap:6px}.mform-tag button{border:none;background:none;color:inherit;cursor:pointer;font-size:12px;padding:0;line-height:1}.mform-tag-input{flex:1;min-width:140px;width:auto}.mform-field.is-pending .mform-control{background-image:linear-gradient(90deg,transparent 0%,rgb(109 75 208 / 12%) 50%,transparent 100%);background-size:200% 100%;animation:mform-pending 1.2s linear infinite}@keyframes mform-pending{0%{background-position:200% 0}to{background-position:-200% 0}}.mform-files{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:4px}.mform-files.is-gallery{flex-direction:row;flex-wrap:wrap;gap:10px}.mform-file{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--mform-muted, #6b6580)}.mform-files.is-gallery .mform-file{flex-direction:column;gap:4px;width:var(--mform-thumb-size, 96px);text-align:center;position:relative}.mform-thumb{width:var(--mform-thumb-size, 96px);height:var(--mform-thumb-size, 96px);object-fit:cover;border-radius:var(--mform-control-radius, 8px);border:1px solid var(--mform-border, #d9d5e6);background:var(--mform-bg, #f6f5fa)}.mform-file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.mform-file-remove{border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer;font-size:12px;padding:0 4px}.mform-file-remove:hover{color:var(--mform-danger, #c62842)}.mform-files.is-gallery .mform-file-remove{position:absolute;top:2px;right:2px;background:var(--mform-surface, #fff);border-radius:50%;width:20px;height:20px;line-height:1;box-shadow:0 1px 4px #1f1b2e33}.mform-reference{position:relative}.mform-ref-list{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:10;margin:0;padding:4px;list-style:none;background:var(--mform-control-bg, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);box-shadow:0 8px 24px #1f1b2e1f;max-height:220px;overflow-y:auto}.mform-ref-list button{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:7px 10px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.mform-ref-list button:hover{background:var(--mform-bg, #f6f5fa)}.mform-tabbar{display:flex;gap:4px;border-bottom:2px solid var(--mform-border, #d9d5e6);margin-bottom:14px}.mform-tab{padding:8px 18px;font:inherit;font-size:14px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.mform-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.mform-grid-row{display:flex;align-items:flex-start;gap:8px;padding:10px 0;border-bottom:1px dashed var(--mform-border, #d9d5e6)}.mform-grid-fields{flex:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--mform-gap, 16px)}.mform-row-remove{border:none;background:none;color:var(--mform-muted, #6b6580);font:inherit;cursor:pointer;padding:6px 8px}.mform-row-remove:hover{color:var(--mform-danger, #c62842)}.mform-row-add{align-self:flex-start;background:none;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);padding:7px 14px;border-radius:var(--mform-control-radius, 8px);font:inherit;font-size:13px;cursor:pointer}.mform-btn{align-self:flex-start;background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border:none;border-radius:var(--mform-control-radius, 8px);padding:11px 26px;font:inherit;font-weight:600;cursor:pointer}.mform-btn:hover{filter:brightness(1.08)}.mform-btn:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:2px}.mform-content{font-size:14px}.mform-unsupported{font-size:13px;color:var(--mform-muted, #6b6580);border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:10px 14px}.mform-steps{display:flex;gap:18px;list-style:none;margin:0 0 4px;padding:0 0 12px;border-bottom:1px solid var(--mform-border, #d9d5e6);flex-wrap:wrap}.mform-step{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--mform-muted, #6b6580)}.mform-step-index{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;border:1.5px solid var(--mform-border, #d9d5e6);font-size:11px;font-weight:600}.mform-step.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600}.mform-step.is-active .mform-step-index{border-color:var(--mform-primary, #6d4bd0);background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.mform-step.is-done .mform-step-index{border-color:var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-wizard-nav{display:flex;gap:10px;padding-top:4px}.mform-btn-secondary{background:none;border:1px solid var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-summary{border:1px solid var(--mform-danger, #c62842);background:var(--mform-danger-bg, #fdf0f2);color:var(--mform-danger, #c62842);border-radius:var(--mform-radius, 10px);padding:12px 16px;font-size:13px}.mform-summary ul{margin:6px 0 0;padding-left:18px}\n"], dependencies: [{ kind: "component", type: FormNodeComponent, selector: "mform-node", inputs: ["node", "engine", "tick", "scope", "bare", "providers", "mode", "notify"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1408
1559
  }
1409
1560
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: FormRendererComponent, decorators: [{
1410
1561
  type: Component,
@@ -1471,7 +1622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
1471
1622
  }
1472
1623
  </form>
1473
1624
  }
1474
- `, styles: [".mform-root{display:flex;flex-direction:column;gap:var(--mform-gap, 16px);font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e)}.mform-node{display:contents}.mform-field{display:flex;flex-direction:column;gap:6px}.mform-label{font-size:var(--mform-label-size, 13px);font-weight:var(--mform-label-weight, 600)}.mform-req{color:var(--mform-danger, #c62842);margin-left:2px}.mform-control{font:inherit;width:100%;padding:var(--mform-control-padding, 9px 12px);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff);color:inherit;box-sizing:border-box}textarea.mform-control{min-height:72px;resize:vertical}.mform-control:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px;border-color:var(--mform-focus, #8e6ff0)}.mform-field.has-error .mform-control{border-color:var(--mform-danger, #c62842)}.mform-desc{font-size:12px;color:var(--mform-muted, #6b6580)}.mform-error{font-size:12px;color:var(--mform-danger, #c62842)}.mform-choices{display:flex;flex-direction:column;gap:6px}.mform-check{display:flex;align-items:center;gap:8px;font-size:14px;cursor:pointer}.mform-check input{width:16px;height:16px;accent-color:var(--mform-primary, #6d4bd0)}.mform-panel{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.mform-panel-head{background:var(--mform-panel-head-bg, linear-gradient(90deg, #efeaff, #f8f6ff));color:var(--mform-panel-head-text, inherit);padding:10px 16px;font-weight:600;font-size:14px;border-bottom:1px solid var(--mform-border, #d9d5e6)}.mform-panel-body,.mform-group,.mform-column,.mform-tabpanel{display:flex;flex-direction:column;gap:var(--mform-gap, 16px)}.mform-panel-body{padding:var(--mform-panel-padding, 16px)}.mform-columns{display:grid;gap:var(--mform-gap, 16px)}@media(max-width:640px){.mform-columns{grid-template-columns:1fr!important}}.mform-affix{display:flex;align-items:center}.mform-affix.has-affix{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff)}.mform-affix.has-affix .mform-control{border:none;background:none;flex:1}.mform-affix.has-affix:focus-within{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px}.mform-prefix,.mform-suffix{padding:0 10px;color:var(--mform-muted, #6b6580);font-size:13px;white-space:nowrap}.mform-tags{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.mform-tag{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-radius:999px;padding:3px 10px;font-size:12px;display:inline-flex;align-items:center;gap:6px}.mform-tag button{border:none;background:none;color:inherit;cursor:pointer;font-size:12px;padding:0;line-height:1}.mform-tag-input{flex:1;min-width:140px;width:auto}.mform-field.is-pending .mform-control{background-image:linear-gradient(90deg,transparent 0%,rgb(109 75 208 / 12%) 50%,transparent 100%);background-size:200% 100%;animation:mform-pending 1.2s linear infinite}@keyframes mform-pending{0%{background-position:200% 0}to{background-position:-200% 0}}.mform-file-name{font-size:12px;color:var(--mform-muted, #6b6580);padding:2px 0}.mform-reference{position:relative}.mform-ref-list{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:10;margin:0;padding:4px;list-style:none;background:var(--mform-control-bg, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);box-shadow:0 8px 24px #1f1b2e1f;max-height:220px;overflow-y:auto}.mform-ref-list button{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:7px 10px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.mform-ref-list button:hover{background:var(--mform-bg, #f6f5fa)}.mform-tabbar{display:flex;gap:4px;border-bottom:2px solid var(--mform-border, #d9d5e6);margin-bottom:14px}.mform-tab{padding:8px 18px;font:inherit;font-size:14px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.mform-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.mform-grid-row{display:flex;align-items:flex-start;gap:8px;padding:10px 0;border-bottom:1px dashed var(--mform-border, #d9d5e6)}.mform-grid-fields{flex:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--mform-gap, 16px)}.mform-row-remove{border:none;background:none;color:var(--mform-muted, #6b6580);font:inherit;cursor:pointer;padding:6px 8px}.mform-row-remove:hover{color:var(--mform-danger, #c62842)}.mform-row-add{align-self:flex-start;background:none;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);padding:7px 14px;border-radius:var(--mform-control-radius, 8px);font:inherit;font-size:13px;cursor:pointer}.mform-btn{align-self:flex-start;background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border:none;border-radius:var(--mform-control-radius, 8px);padding:11px 26px;font:inherit;font-weight:600;cursor:pointer}.mform-btn:hover{filter:brightness(1.08)}.mform-btn:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:2px}.mform-content{font-size:14px}.mform-unsupported{font-size:13px;color:var(--mform-muted, #6b6580);border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:10px 14px}.mform-steps{display:flex;gap:18px;list-style:none;margin:0 0 4px;padding:0 0 12px;border-bottom:1px solid var(--mform-border, #d9d5e6);flex-wrap:wrap}.mform-step{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--mform-muted, #6b6580)}.mform-step-index{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;border:1.5px solid var(--mform-border, #d9d5e6);font-size:11px;font-weight:600}.mform-step.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600}.mform-step.is-active .mform-step-index{border-color:var(--mform-primary, #6d4bd0);background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.mform-step.is-done .mform-step-index{border-color:var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-wizard-nav{display:flex;gap:10px;padding-top:4px}.mform-btn-secondary{background:none;border:1px solid var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-summary{border:1px solid var(--mform-danger, #c62842);background:var(--mform-danger-bg, #fdf0f2);color:var(--mform-danger, #c62842);border-radius:var(--mform-radius, 10px);padding:12px 16px;font-size:13px}.mform-summary ul{margin:6px 0 0;padding-left:18px}\n"] }]
1625
+ `, styles: [".mform-root{display:flex;flex-direction:column;gap:var(--mform-gap, 16px);font-family:var(--mform-font, system-ui, \"Segoe UI\", sans-serif);color:var(--mform-text, #1f1b2e)}.mform-node{display:contents}.mform-field{display:flex;flex-direction:column;gap:6px}.mform-label{font-size:var(--mform-label-size, 13px);font-weight:var(--mform-label-weight, 600)}.mform-req{color:var(--mform-danger, #c62842);margin-left:2px}.mform-control{font:inherit;width:100%;padding:var(--mform-control-padding, 9px 12px);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff);color:inherit;box-sizing:border-box}textarea.mform-control{min-height:72px;resize:vertical}.mform-control:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px;border-color:var(--mform-focus, #8e6ff0)}.mform-field.has-error .mform-control{border-color:var(--mform-danger, #c62842)}.mform-desc{font-size:12px;color:var(--mform-muted, #6b6580)}.mform-error{font-size:12px;color:var(--mform-danger, #c62842)}.mform-choices{display:flex;flex-direction:column;gap:6px}.mform-check{display:flex;align-items:center;gap:8px;font-size:14px;cursor:pointer}.mform-check input{width:16px;height:16px;accent-color:var(--mform-primary, #6d4bd0)}.mform-panel{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);overflow:hidden}.mform-panel-head{background:var(--mform-panel-head-bg, linear-gradient(90deg, #efeaff, #f8f6ff));color:var(--mform-panel-head-text, inherit);padding:10px 16px;font-weight:600;font-size:14px;border-bottom:1px solid var(--mform-border, #d9d5e6)}.mform-panel-body,.mform-group,.mform-column,.mform-tabpanel{display:flex;flex-direction:column;gap:var(--mform-gap, 16px)}.mform-panel-body{padding:var(--mform-panel-padding, 16px)}.mform-columns{display:grid;gap:var(--mform-gap, 16px)}@media(max-width:640px){.mform-columns{grid-template-columns:1fr!important}}.mform-affix{display:flex;align-items:center}.mform-affix.has-affix{border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);background:var(--mform-control-bg, #fff)}.mform-affix.has-affix .mform-control{border:none;background:none;flex:1}.mform-affix.has-affix:focus-within{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:1px}.mform-prefix,.mform-suffix{padding:0 10px;color:var(--mform-muted, #6b6580);font-size:13px;white-space:nowrap}.mform-tags{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.mform-tag{background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border-radius:999px;padding:3px 10px;font-size:12px;display:inline-flex;align-items:center;gap:6px}.mform-tag button{border:none;background:none;color:inherit;cursor:pointer;font-size:12px;padding:0;line-height:1}.mform-tag-input{flex:1;min-width:140px;width:auto}.mform-field.is-pending .mform-control{background-image:linear-gradient(90deg,transparent 0%,rgb(109 75 208 / 12%) 50%,transparent 100%);background-size:200% 100%;animation:mform-pending 1.2s linear infinite}@keyframes mform-pending{0%{background-position:200% 0}to{background-position:-200% 0}}.mform-files{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:4px}.mform-files.is-gallery{flex-direction:row;flex-wrap:wrap;gap:10px}.mform-file{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--mform-muted, #6b6580)}.mform-files.is-gallery .mform-file{flex-direction:column;gap:4px;width:var(--mform-thumb-size, 96px);text-align:center;position:relative}.mform-thumb{width:var(--mform-thumb-size, 96px);height:var(--mform-thumb-size, 96px);object-fit:cover;border-radius:var(--mform-control-radius, 8px);border:1px solid var(--mform-border, #d9d5e6);background:var(--mform-bg, #f6f5fa)}.mform-file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.mform-file-remove{border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer;font-size:12px;padding:0 4px}.mform-file-remove:hover{color:var(--mform-danger, #c62842)}.mform-files.is-gallery .mform-file-remove{position:absolute;top:2px;right:2px;background:var(--mform-surface, #fff);border-radius:50%;width:20px;height:20px;line-height:1;box-shadow:0 1px 4px #1f1b2e33}.mform-reference{position:relative}.mform-ref-list{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:10;margin:0;padding:4px;list-style:none;background:var(--mform-control-bg, #fff);border:1px solid var(--mform-border, #d9d5e6);border-radius:var(--mform-control-radius, 8px);box-shadow:0 8px 24px #1f1b2e1f;max-height:220px;overflow-y:auto}.mform-ref-list button{display:block;width:100%;text-align:left;font:inherit;font-size:13px;padding:7px 10px;border:none;border-radius:6px;background:none;color:inherit;cursor:pointer}.mform-ref-list button:hover{background:var(--mform-bg, #f6f5fa)}.mform-tabbar{display:flex;gap:4px;border-bottom:2px solid var(--mform-border, #d9d5e6);margin-bottom:14px}.mform-tab{padding:8px 18px;font:inherit;font-size:14px;border:none;background:none;color:var(--mform-muted, #6b6580);cursor:pointer}.mform-tab.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600;border-bottom:2px solid var(--mform-primary, #6d4bd0);margin-bottom:-2px}.mform-grid-row{display:flex;align-items:flex-start;gap:8px;padding:10px 0;border-bottom:1px dashed var(--mform-border, #d9d5e6)}.mform-grid-fields{flex:1;display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--mform-gap, 16px)}.mform-row-remove{border:none;background:none;color:var(--mform-muted, #6b6580);font:inherit;cursor:pointer;padding:6px 8px}.mform-row-remove:hover{color:var(--mform-danger, #c62842)}.mform-row-add{align-self:flex-start;background:none;border:1px dashed var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0);padding:7px 14px;border-radius:var(--mform-control-radius, 8px);font:inherit;font-size:13px;cursor:pointer}.mform-btn{align-self:flex-start;background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff);border:none;border-radius:var(--mform-control-radius, 8px);padding:11px 26px;font:inherit;font-weight:600;cursor:pointer}.mform-btn:hover{filter:brightness(1.08)}.mform-btn:focus-visible{outline:2px solid var(--mform-focus, #8e6ff0);outline-offset:2px}.mform-content{font-size:14px}.mform-unsupported{font-size:13px;color:var(--mform-muted, #6b6580);border:1px dashed var(--mform-border, #d9d5e6);border-radius:var(--mform-radius, 10px);padding:10px 14px}.mform-steps{display:flex;gap:18px;list-style:none;margin:0 0 4px;padding:0 0 12px;border-bottom:1px solid var(--mform-border, #d9d5e6);flex-wrap:wrap}.mform-step{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--mform-muted, #6b6580)}.mform-step-index{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;border:1.5px solid var(--mform-border, #d9d5e6);font-size:11px;font-weight:600}.mform-step.is-active{color:var(--mform-primary, #6d4bd0);font-weight:600}.mform-step.is-active .mform-step-index{border-color:var(--mform-primary, #6d4bd0);background:var(--mform-primary, #6d4bd0);color:var(--mform-primary-contrast, #fff)}.mform-step.is-done .mform-step-index{border-color:var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-wizard-nav{display:flex;gap:10px;padding-top:4px}.mform-btn-secondary{background:none;border:1px solid var(--mform-primary, #6d4bd0);color:var(--mform-primary, #6d4bd0)}.mform-summary{border:1px solid var(--mform-danger, #c62842);background:var(--mform-danger-bg, #fdf0f2);color:var(--mform-danger, #c62842);border-radius:var(--mform-radius, 10px);padding:12px 16px;font-size:13px}.mform-summary ul{margin:6px 0 0;padding-left:18px}\n"] }]
1475
1626
  }], ctorParameters: () => [], propDecorators: { schema: [{ type: i0.Input, args: [{ isSignal: true, alias: "schema", required: false }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], initialData: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialData", required: false }] }], optionsProviders: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionsProviders", required: false }] }], messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }], validators: [{ type: i0.Input, args: [{ isSignal: true, alias: "validators", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], submitHandler: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitHandler", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], submitted: [{ type: i0.Output, args: ["submitted"] }], valueChanged: [{ type: i0.Output, args: ["valueChanged"] }] } });
1476
1627
 
1477
1628
  /*