@momentumcms/admin 0.5.1 → 0.5.3

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 (25) hide show
  1. package/fesm2022/{momentumcms-admin-array-field.component-pqA3_nC8.mjs → momentumcms-admin-array-field.component-ChjP5zK9.mjs} +2 -2
  2. package/fesm2022/{momentumcms-admin-array-field.component-pqA3_nC8.mjs.map → momentumcms-admin-array-field.component-ChjP5zK9.mjs.map} +1 -1
  3. package/fesm2022/{momentumcms-admin-blocks-field.component-88TEhVm4.mjs → momentumcms-admin-blocks-field.component-Dl0FxGnf.mjs} +119 -30
  4. package/fesm2022/momentumcms-admin-blocks-field.component-Dl0FxGnf.mjs.map +1 -0
  5. package/fesm2022/{momentumcms-admin-collapsible-field.component-D5Jc8h2Q.mjs → momentumcms-admin-collapsible-field.component-CSLOT0Dp.mjs} +2 -2
  6. package/fesm2022/{momentumcms-admin-collapsible-field.component-D5Jc8h2Q.mjs.map → momentumcms-admin-collapsible-field.component-CSLOT0Dp.mjs.map} +1 -1
  7. package/fesm2022/{momentumcms-admin-global-edit.page-D4QNE5AM.mjs → momentumcms-admin-global-edit.page-DHr7Icl6.mjs} +2 -2
  8. package/fesm2022/{momentumcms-admin-global-edit.page-D4QNE5AM.mjs.map → momentumcms-admin-global-edit.page-DHr7Icl6.mjs.map} +1 -1
  9. package/fesm2022/{momentumcms-admin-group-field.component-Cenc5zMW.mjs → momentumcms-admin-group-field.component-Bofhumd5.mjs} +2 -2
  10. package/fesm2022/{momentumcms-admin-group-field.component-Cenc5zMW.mjs.map → momentumcms-admin-group-field.component-Bofhumd5.mjs.map} +1 -1
  11. package/fesm2022/{momentumcms-admin-momentumcms-admin-5WigESOC.mjs → momentumcms-admin-momentumcms-admin-D8WvqCxe.mjs} +793 -25
  12. package/fesm2022/momentumcms-admin-momentumcms-admin-D8WvqCxe.mjs.map +1 -0
  13. package/fesm2022/{momentumcms-admin-relationship-field.component-DlCdpcRy.mjs → momentumcms-admin-relationship-field.component-DSZhc5MP.mjs} +8 -3
  14. package/fesm2022/{momentumcms-admin-relationship-field.component-DlCdpcRy.mjs.map → momentumcms-admin-relationship-field.component-DSZhc5MP.mjs.map} +1 -1
  15. package/fesm2022/{momentumcms-admin-rich-text-field.component-BUziCgyn.mjs → momentumcms-admin-rich-text-field.component-BIUu6NXa.mjs} +2 -2
  16. package/fesm2022/{momentumcms-admin-rich-text-field.component-BUziCgyn.mjs.map → momentumcms-admin-rich-text-field.component-BIUu6NXa.mjs.map} +1 -1
  17. package/fesm2022/{momentumcms-admin-row-field.component-fFTcYU-P.mjs → momentumcms-admin-row-field.component-DBzqzooT.mjs} +2 -2
  18. package/fesm2022/{momentumcms-admin-row-field.component-fFTcYU-P.mjs.map → momentumcms-admin-row-field.component-DBzqzooT.mjs.map} +1 -1
  19. package/fesm2022/{momentumcms-admin-tabs-field.component-D_T_JZej.mjs → momentumcms-admin-tabs-field.component-BsnCWC5J.mjs} +2 -2
  20. package/fesm2022/{momentumcms-admin-tabs-field.component-D_T_JZej.mjs.map → momentumcms-admin-tabs-field.component-BsnCWC5J.mjs.map} +1 -1
  21. package/fesm2022/momentumcms-admin.mjs +1 -1
  22. package/package.json +1 -1
  23. package/types/momentumcms-admin.d.ts +127 -62
  24. package/fesm2022/momentumcms-admin-blocks-field.component-88TEhVm4.mjs.map +0 -1
  25. package/fesm2022/momentumcms-admin-momentumcms-admin-5WigESOC.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { Routes, CanActivateFn, CanDeactivateFn } from '@angular/router';
2
2
  import * as _angular_core from '@angular/core';
3
3
  import { Type, InjectionToken, Signal, Provider, OnInit, WritableSignal, makeEnvironmentProviders } from '@angular/core';
4
- import { CollectionConfig, GlobalConfig, PluginAdminRouteDescriptor, MomentumPlugin, MomentumConfig, MomentumAdminConfig, MediaDocument, AdminConfig, Field, DocumentStatus as DocumentStatus$1, BlockConfig, UploadField } from '@momentumcms/core';
4
+ import { CollectionConfig, GlobalConfig, PluginAdminRouteDescriptor, MomentumPlugin, MomentumConfig, MomentumAdminConfig, MediaDocument, AdminConfig, ImageSizeConfig, Field, DocumentStatus as DocumentStatus$1, BlockConfig, UploadField } from '@momentumcms/core';
5
5
  import { HttpContextToken, HttpInterceptorFn } from '@angular/common/http';
6
6
  import { Observable } from 'rxjs';
7
7
  import * as _momentumcms_admin from '@momentumcms/admin';
@@ -2203,6 +2203,10 @@ interface MediaItem$1 {
2203
2203
  alt?: string;
2204
2204
  width?: number;
2205
2205
  height?: number;
2206
+ focalPoint?: {
2207
+ x: number;
2208
+ y: number;
2209
+ };
2206
2210
  }
2207
2211
  /**
2208
2212
  * Media Library Page
@@ -2211,6 +2215,7 @@ interface MediaItem$1 {
2211
2215
  */
2212
2216
  declare class MediaLibraryPage {
2213
2217
  private readonly document;
2218
+ private readonly route;
2214
2219
  private readonly api;
2215
2220
  private readonly uploadService;
2216
2221
  private readonly feedback;
@@ -2218,6 +2223,8 @@ declare class MediaLibraryPage {
2218
2223
  private readonly dialog;
2219
2224
  private readonly destroyRef;
2220
2225
  private readonly uploadSubscriptions;
2226
+ /** Image sizes config from the media collection (for crop previews in edit dialog) */
2227
+ readonly mediaImageSizes: ImageSizeConfig[];
2221
2228
  /** Internal state */
2222
2229
  readonly isLoading: _angular_core.WritableSignal<boolean>;
2223
2230
  readonly mediaItems: _angular_core.WritableSignal<MediaItem$1[]>;
@@ -2507,8 +2514,10 @@ declare class EntityFormWidget<T extends Entity = Entity> {
2507
2514
  readonly draftSaved: _angular_core.OutputEmitterRef<void>;
2508
2515
  /** Model signal — the single source of truth for form data */
2509
2516
  readonly formModel: _angular_core.WritableSignal<Record<string, unknown>>;
2510
- /** Alias for backward compatibility (CollectionEditPage reads formData) */
2511
- readonly formData: _angular_core.WritableSignal<Record<string, unknown>>;
2517
+ /** Reactive form data that tracks Signal Forms changes for downstream consumers (e.g. live preview).
2518
+ * Reads the root FieldState value directly so it re-triggers when any field value changes,
2519
+ * unlike formModel which may keep the same object reference after in-place mutations. */
2520
+ readonly formData: _angular_core.Signal<Record<string, unknown>>;
2512
2521
  /** Signal forms tree — created once when collection is available */
2513
2522
  readonly entityForm: _angular_core.WritableSignal<_angular_forms_signals.FieldTree<Record<string, unknown>, string | number> | null>;
2514
2523
  /** Original data for edit mode */
@@ -2523,8 +2532,35 @@ declare class EntityFormWidget<T extends Entity = Entity> {
2523
2532
  readonly isUploadingFile: _angular_core.WritableSignal<boolean>;
2524
2533
  readonly uploadFileProgress: _angular_core.WritableSignal<number>;
2525
2534
  readonly uploadFileError: _angular_core.WritableSignal<string | null>;
2535
+ /** Preview URL for the pending image file (focal point picker) */
2536
+ readonly pendingFileUrl: _angular_core.WritableSignal<string | null>;
2537
+ /** Detected dimensions of the pending image */
2538
+ readonly pendingImageDimensions: _angular_core.WritableSignal<{
2539
+ width: number;
2540
+ height: number;
2541
+ }>;
2526
2542
  /** Whether the collection is an upload collection */
2527
2543
  readonly isUploadCol: _angular_core.Signal<boolean>;
2544
+ /** Whether the current file (pending or existing) is an image */
2545
+ readonly isImageFile: _angular_core.Signal<boolean>;
2546
+ /** Image sizes from collection upload config */
2547
+ readonly uploadImageSizes: _angular_core.Signal<ImageSizeConfig[]>;
2548
+ /** Image URL for the focal point picker */
2549
+ readonly focalPointImageUrl: _angular_core.Signal<string>;
2550
+ /** Current focal point value */
2551
+ readonly currentFocalPoint: _angular_core.Signal<{
2552
+ x: number;
2553
+ y: number;
2554
+ }>;
2555
+ /** Natural image dimensions (pending file detection or existing media) */
2556
+ readonly imageNaturalDimensions: _angular_core.Signal<{
2557
+ width: number;
2558
+ height: number;
2559
+ }>;
2560
+ /** Alt text for the focal point picker */
2561
+ readonly focalPointAlt: _angular_core.Signal<string>;
2562
+ /** Generated image sizes from the form model */
2563
+ readonly formModelSizes: _angular_core.Signal<Record<string, unknown> | null>;
2528
2564
  /** Whether the form has been set up */
2529
2565
  private formCreated;
2530
2566
  /** Whether the form has unsaved changes (from signal forms dirty tracking) */
@@ -2565,6 +2601,13 @@ declare class EntityFormWidget<T extends Entity = Entity> {
2565
2601
  * Auto-populates metadata fields in the form model.
2566
2602
  */
2567
2603
  onFileSelected(file: File): void;
2604
+ /**
2605
+ * Handle focal point change from the picker.
2606
+ */
2607
+ onFocalPointChange(fp: {
2608
+ x: number;
2609
+ y: number;
2610
+ }): void;
2568
2611
  /**
2569
2612
  * Handle file removed from the upload zone.
2570
2613
  */
@@ -2636,6 +2679,63 @@ interface EntityViewActionEvent {
2636
2679
  entity: Entity;
2637
2680
  }
2638
2681
 
2682
+ /**
2683
+ * Media document data for preview.
2684
+ */
2685
+ interface MediaPreviewData {
2686
+ url?: string;
2687
+ path?: string;
2688
+ mimeType?: string;
2689
+ filename?: string;
2690
+ alt?: string;
2691
+ }
2692
+ /**
2693
+ * Media Preview Component
2694
+ *
2695
+ * Displays a preview of media based on its type:
2696
+ * - Images: Thumbnail preview
2697
+ * - Videos: Video icon with optional poster
2698
+ * - Audio: Audio icon
2699
+ * - Documents: Document icon
2700
+ * - Other: Generic file icon
2701
+ *
2702
+ * @example
2703
+ * ```html
2704
+ * <mcms-media-preview
2705
+ * [media]="mediaDocument"
2706
+ * [size]="'md'"
2707
+ * />
2708
+ * ```
2709
+ */
2710
+ declare class MediaPreviewComponent {
2711
+ /** Media data to preview */
2712
+ readonly media: _angular_core.InputSignal<MediaPreviewData | null>;
2713
+ /** Size of the preview */
2714
+ readonly size: _angular_core.InputSignal<"xs" | "sm" | "md" | "lg" | "xl">;
2715
+ /** Custom class override */
2716
+ readonly class: _angular_core.InputSignal<string>;
2717
+ /** Whether to show rounded corners */
2718
+ readonly rounded: _angular_core.InputSignal<boolean>;
2719
+ /** Host classes */
2720
+ readonly hostClasses: _angular_core.Signal<string>;
2721
+ /** Size classes map */
2722
+ private readonly sizeClasses;
2723
+ /** Icon size classes */
2724
+ readonly iconClasses: _angular_core.Signal<string>;
2725
+ /** Whether the media is an image */
2726
+ readonly isImage: _angular_core.Signal<boolean>;
2727
+ /** Whether the media is a video */
2728
+ readonly isVideo: _angular_core.Signal<boolean>;
2729
+ /** Whether the media is audio */
2730
+ readonly isAudio: _angular_core.Signal<boolean>;
2731
+ /** Image URL for preview */
2732
+ readonly imageUrl: _angular_core.Signal<string>;
2733
+ /** Icon name based on media type */
2734
+ readonly iconName: _angular_core.Signal<"<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h1.5C5.496 19.5 6 18.996 6 18.375m-3.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-1.5A1.125 1.125 0 0 1 18 18.375M20.625 4.5H3.375m17.25 0c.621 0 1.125.504 1.125 1.125M20.625 4.5h-1.5C18.504 4.5 18 5.004 18 5.625m3.75 0v1.5c0 .621-.504 1.125-1.125 1.125M3.375 4.5c-.621 0-1.125.504-1.125 1.125M3.375 4.5h1.5C5.496 4.5 6 5.004 6 5.625m-3.75 0v1.5c0 .621.504 1.125 1.125 1.125m0 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m1.5-3.75C5.496 8.25 6 7.746 6 7.125v-1.5M4.875 8.25C5.496 8.25 6 8.754 6 9.375v1.5m0-5.25v5.25m0-5.25C6 5.004 6.504 4.5 7.125 4.5h9.75c.621 0 1.125.504 1.125 1.125m1.125 2.625h1.5m-1.5 0A1.125 1.125 0 0 1 18 7.125v-1.5m1.125 2.625c-.621 0-1.125.504-1.125 1.125v1.5m2.625-2.625c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125M18 5.625v5.25M7.125 12h9.75m-9.75 0A1.125 1.125 0 0 1 6 10.875M7.125 12C6.504 12 6 12.504 6 13.125m0-2.25C6 11.496 5.496 12 4.875 12M18 10.875c0 .621-.504 1.125-1.125 1.125M18 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m-12 5.25v-5.25m0 5.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125m-12 0v-1.5c0-.621-.504-1.125-1.125-1.125M18 18.375v-5.25m0 5.25v-1.5c0-.621.504-1.125 1.125-1.125M18 13.125v1.5c0 .621.504 1.125 1.125 1.125M18 13.125c0-.621.504-1.125 1.125-1.125M6 13.125v1.5c0 .621-.504 1.125-1.125 1.125M6 13.125C6 12.504 5.496 12 4.875 12m-1.5 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M19.125 12h1.5m0 0c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h1.5m14.25 0h1.5\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m9 9 10.5-3m0 6.553v3.75a2.25 2.25 0 0 1-1.632 2.163l-1.32.377a1.803 1.803 0 1 1-.99-3.467l2.31-.66a2.25 2.25 0 0 0 1.632-2.163Zm0 0V2.25L9 5.25v10.303m0 0v3.75a2.25 2.25 0 0 1-1.632 2.163l-1.32.377a1.803 1.803 0 0 1-.99-3.467l2.31-.66A2.25 2.25 0 0 0 9 15.553Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m20.25 7.5-.625 10.632a2.25 2.25 0 0 1-2.247 2.118H6.622a2.25 2.25 0 0 1-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z\"></path></svg>">;
2735
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MediaPreviewComponent, never>;
2736
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MediaPreviewComponent, "mcms-media-preview", never, { "media": { "alias": "media"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "class": { "alias": "class"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2737
+ }
2738
+
2639
2739
  /**
2640
2740
  * Entity View Widget
2641
2741
  *
@@ -2703,6 +2803,28 @@ declare class EntityViewWidget<T extends Entity = Entity> {
2703
2803
  readonly canEdit: _angular_core.Signal<boolean>;
2704
2804
  /** Whether user can delete */
2705
2805
  readonly canDelete: _angular_core.Signal<boolean>;
2806
+ /** Whether this collection is an upload collection */
2807
+ readonly isUploadCol: _angular_core.Signal<boolean>;
2808
+ /** Whether the entity is an image */
2809
+ readonly isEntityImage: _angular_core.Signal<boolean>;
2810
+ /** Media URL for preview */
2811
+ readonly entityMediaUrl: _angular_core.Signal<string>;
2812
+ /** Focal point from entity data */
2813
+ readonly entityFocalPoint: _angular_core.Signal<{
2814
+ x: number;
2815
+ y: number;
2816
+ }>;
2817
+ /** Image dimensions from entity data */
2818
+ readonly entityDimensions: _angular_core.Signal<{
2819
+ width: number;
2820
+ height: number;
2821
+ }>;
2822
+ /** Image sizes from collection upload config */
2823
+ readonly viewImageSizes: _angular_core.Signal<ImageSizeConfig[]>;
2824
+ /** Generated image sizes from entity data */
2825
+ readonly entitySizes: _angular_core.Signal<Record<string, unknown> | null>;
2826
+ /** Media preview data for non-image files */
2827
+ readonly entityMediaPreview: _angular_core.Signal<MediaPreviewData | null>;
2706
2828
  /** Whether collection has soft delete enabled */
2707
2829
  readonly hasSoftDelete: _angular_core.Signal<boolean>;
2708
2830
  /** Whether the current entity is soft-deleted */
@@ -3026,63 +3148,6 @@ declare class PublishControlsWidget {
3026
3148
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<PublishControlsWidget, "mcms-publish-controls", never, { "collection": { "alias": "collection"; "required": true; "isSignal": true; }; "documentId": { "alias": "documentId"; "required": true; "isSignal": true; }; "documentLabel": { "alias": "documentLabel"; "required": false; "isSignal": true; }; "initialStatus": { "alias": "initialStatus"; "required": false; "isSignal": true; }; }, { "statusChanged": "statusChanged"; }, never, never, true, never>;
3027
3149
  }
3028
3150
 
3029
- /**
3030
- * Media document data for preview.
3031
- */
3032
- interface MediaPreviewData {
3033
- url?: string;
3034
- path?: string;
3035
- mimeType?: string;
3036
- filename?: string;
3037
- alt?: string;
3038
- }
3039
- /**
3040
- * Media Preview Component
3041
- *
3042
- * Displays a preview of media based on its type:
3043
- * - Images: Thumbnail preview
3044
- * - Videos: Video icon with optional poster
3045
- * - Audio: Audio icon
3046
- * - Documents: Document icon
3047
- * - Other: Generic file icon
3048
- *
3049
- * @example
3050
- * ```html
3051
- * <mcms-media-preview
3052
- * [media]="mediaDocument"
3053
- * [size]="'md'"
3054
- * />
3055
- * ```
3056
- */
3057
- declare class MediaPreviewComponent {
3058
- /** Media data to preview */
3059
- readonly media: _angular_core.InputSignal<MediaPreviewData | null>;
3060
- /** Size of the preview */
3061
- readonly size: _angular_core.InputSignal<"xs" | "sm" | "md" | "lg" | "xl">;
3062
- /** Custom class override */
3063
- readonly class: _angular_core.InputSignal<string>;
3064
- /** Whether to show rounded corners */
3065
- readonly rounded: _angular_core.InputSignal<boolean>;
3066
- /** Host classes */
3067
- readonly hostClasses: _angular_core.Signal<string>;
3068
- /** Size classes map */
3069
- private readonly sizeClasses;
3070
- /** Icon size classes */
3071
- readonly iconClasses: _angular_core.Signal<string>;
3072
- /** Whether the media is an image */
3073
- readonly isImage: _angular_core.Signal<boolean>;
3074
- /** Whether the media is a video */
3075
- readonly isVideo: _angular_core.Signal<boolean>;
3076
- /** Whether the media is audio */
3077
- readonly isAudio: _angular_core.Signal<boolean>;
3078
- /** Image URL for preview */
3079
- readonly imageUrl: _angular_core.Signal<string>;
3080
- /** Icon name based on media type */
3081
- readonly iconName: _angular_core.Signal<"<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h1.5C5.496 19.5 6 18.996 6 18.375m-3.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-1.5A1.125 1.125 0 0 1 18 18.375M20.625 4.5H3.375m17.25 0c.621 0 1.125.504 1.125 1.125M20.625 4.5h-1.5C18.504 4.5 18 5.004 18 5.625m3.75 0v1.5c0 .621-.504 1.125-1.125 1.125M3.375 4.5c-.621 0-1.125.504-1.125 1.125M3.375 4.5h1.5C5.496 4.5 6 5.004 6 5.625m-3.75 0v1.5c0 .621.504 1.125 1.125 1.125m0 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m1.5-3.75C5.496 8.25 6 7.746 6 7.125v-1.5M4.875 8.25C5.496 8.25 6 8.754 6 9.375v1.5m0-5.25v5.25m0-5.25C6 5.004 6.504 4.5 7.125 4.5h9.75c.621 0 1.125.504 1.125 1.125m1.125 2.625h1.5m-1.5 0A1.125 1.125 0 0 1 18 7.125v-1.5m1.125 2.625c-.621 0-1.125.504-1.125 1.125v1.5m2.625-2.625c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125M18 5.625v5.25M7.125 12h9.75m-9.75 0A1.125 1.125 0 0 1 6 10.875M7.125 12C6.504 12 6 12.504 6 13.125m0-2.25C6 11.496 5.496 12 4.875 12M18 10.875c0 .621-.504 1.125-1.125 1.125M18 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m-12 5.25v-5.25m0 5.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125m-12 0v-1.5c0-.621-.504-1.125-1.125-1.125M18 18.375v-5.25m0 5.25v-1.5c0-.621.504-1.125 1.125-1.125M18 13.125v1.5c0 .621.504 1.125 1.125 1.125M18 13.125c0-.621.504-1.125 1.125-1.125M6 13.125v1.5c0 .621-.504 1.125-1.125 1.125M6 13.125C6 12.504 5.496 12 4.875 12m-1.5 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M19.125 12h1.5m0 0c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h1.5m14.25 0h1.5\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m9 9 10.5-3m0 6.553v3.75a2.25 2.25 0 0 1-1.632 2.163l-1.32.377a1.803 1.803 0 1 1-.99-3.467l2.31-.66a2.25 2.25 0 0 0 1.632-2.163Zm0 0V2.25L9 5.25v10.303m0 0v3.75a2.25 2.25 0 0 1-1.632 2.163l-1.32.377a1.803 1.803 0 0 1-.99-3.467l2.31-.66A2.25 2.25 0 0 0 9 15.553Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m20.25 7.5-.625 10.632a2.25 2.25 0 0 1-2.247 2.118H6.622a2.25 2.25 0 0 1-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z\"></path></svg>" | "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\" style=\"stroke-width:var(--ng-icon__stroke-width, 1.5)\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z\"></path></svg>">;
3082
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<MediaPreviewComponent, never>;
3083
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<MediaPreviewComponent, "mcms-media-preview", never, { "media": { "alias": "media"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "class": { "alias": "class"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3084
- }
3085
-
3086
3151
  /** Device size preset for the preview iframe. */
3087
3152
  type DeviceSize = 'desktop' | 'tablet' | 'mobile';
3088
3153
  /**
@@ -3399,7 +3464,7 @@ declare class FieldRenderer {
3399
3464
  /** Error from lazy loading failure */
3400
3465
  readonly loadError: _angular_core.WritableSignal<Error | null>;
3401
3466
  /** Registry key: maps field type + editor config to renderer registry keys */
3402
- readonly registryKey: _angular_core.Signal<"number" | "slug" | "email" | "json" | "text" | "textarea" | "richText" | "date" | "checkbox" | "select" | "radio" | "password" | "upload" | "relationship" | "array" | "group" | "blocks" | "point" | "tabs" | "collapsible" | "row" | "blocks-visual" | "json-email-builder" | "json-form-builder">;
3467
+ readonly registryKey: _angular_core.Signal<"number" | "text" | "textarea" | "richText" | "date" | "checkbox" | "select" | "radio" | "email" | "password" | "upload" | "relationship" | "array" | "group" | "blocks" | "json" | "point" | "slug" | "tabs" | "collapsible" | "row" | "blocks-visual" | "json-email-builder" | "json-form-builder">;
3403
3468
  /** Inputs to pass to the dynamically loaded component via NgComponentOutlet */
3404
3469
  readonly rendererInputs: _angular_core.Signal<{
3405
3470
  field: Field;
@@ -3444,7 +3509,7 @@ declare class TextFieldRenderer {
3444
3509
  /** Whether to use textarea */
3445
3510
  readonly isTextarea: _angular_core.Signal<boolean>;
3446
3511
  /** Input type (text, email, etc.) */
3447
- readonly inputType: _angular_core.Signal<"email" | "text">;
3512
+ readonly inputType: _angular_core.Signal<"text" | "email">;
3448
3513
  /** Number of rows for textarea */
3449
3514
  readonly rows: _angular_core.Signal<number>;
3450
3515
  /** String value from FieldState */
@@ -1 +0,0 @@
1
- {"version":3,"file":"momentumcms-admin-blocks-field.component-88TEhVm4.mjs","sources":["../../../../libs/admin/src/lib/widgets/entity-form/field-renderers/blocks-field.component.ts"],"sourcesContent":["import {\n\tChangeDetectionStrategy,\n\tComponent,\n\tcomputed,\n\teffect,\n\tinput,\n\tuntracked,\n} from '@angular/core';\nimport {\n\tCdkDropList,\n\tCdkDrag,\n\tCdkDragHandle,\n\ttype CdkDragDrop,\n\tmoveItemInArray,\n} from '@angular/cdk/drag-drop';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport { heroPlus, heroTrash, heroBars2 } from '@ng-icons/heroicons/outline';\nimport {\n\tCard,\n\tCardHeader,\n\tCardTitle,\n\tCardContent,\n\tCardFooter,\n\tButton,\n\tBadge,\n} from '@momentumcms/ui';\nimport { humanizeFieldName } from '@momentumcms/core';\nimport type { Field, BlockConfig } from '@momentumcms/core';\nimport type { EntityFormMode } from '../entity-form.types';\nimport {\n\tgetFieldNodeState,\n\tgetSubNode,\n\tisRecord,\n\tgetFieldDefaultValue,\n\tnormalizeBlockDefaults,\n} from '../entity-form.types';\nimport { FieldRenderer } from './field-renderer.component';\n\n/** Shape of a block item in the stored data */\ninterface BlockItem {\n\tblockType: string;\n\t[key: string]: unknown;\n}\n\n/**\n * Blocks field renderer.\n *\n * Renders a list of typed blocks. Each block has a `blockType` discriminator\n * and type-specific fields. Users can add, remove, and reorder blocks.\n * A dropdown allows selecting which block type to add.\n *\n * Data container pattern: passes block sub-field FieldTree nodes via\n * getSubNode(getSubNode(formNode, blockIndex), subFieldName).\n * Block mutations use nodeState.value.set(newArray).\n */\n@Component({\n\tselector: 'mcms-blocks-field-renderer',\n\timports: [\n\t\tCard,\n\t\tCardHeader,\n\t\tCardTitle,\n\t\tCardContent,\n\t\tCardFooter,\n\t\tButton,\n\t\tBadge,\n\t\tNgIcon,\n\t\tCdkDropList,\n\t\tCdkDrag,\n\t\tCdkDragHandle,\n\t\tFieldRenderer,\n\t],\n\tproviders: [provideIcons({ heroPlus, heroTrash, heroBars2 })],\n\tchangeDetection: ChangeDetectionStrategy.OnPush,\n\ttemplate: `\n\t\t<mcms-card>\n\t\t\t<mcms-card-header>\n\t\t\t\t<div class=\"flex items-center justify-between\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<mcms-card-title>{{ label() }}</mcms-card-title>\n\t\t\t\t\t\t@if (description()) {\n\t\t\t\t\t\t\t<p class=\"text-sm text-muted-foreground mt-1\">{{ description() }}</p>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<span class=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t{{ blocks().length }}{{ maxRows() ? ' / ' + maxRows() : '' }} blocks\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</mcms-card-header>\n\t\t\t<mcms-card-content>\n\t\t\t\t@if (blocks().length === 0) {\n\t\t\t\t\t<p class=\"text-sm text-muted-foreground py-4 text-center\">\n\t\t\t\t\t\tNo blocks yet. Add a block to get started.\n\t\t\t\t\t</p>\n\t\t\t\t} @else {\n\t\t\t\t\t<div\n\t\t\t\t\t\tcdkDropList\n\t\t\t\t\t\t(cdkDropListDropped)=\"onDrop($event)\"\n\t\t\t\t\t\tclass=\"space-y-3\"\n\t\t\t\t\t\trole=\"list\"\n\t\t\t\t\t\taria-label=\"Content blocks\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@for (block of blocks(); track $index; let i = $index) {\n\t\t\t\t\t\t\t<div cdkDrag class=\"border rounded-lg bg-card\" [cdkDragDisabled]=\"isDisabled()\">\n\t\t\t\t\t\t\t\t<div class=\"flex items-center gap-3 px-4 py-2 border-b bg-muted/50 rounded-t-lg\">\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tcdkDragHandle\n\t\t\t\t\t\t\t\t\t\tclass=\"cursor-grab text-muted-foreground hover:text-foreground\"\n\t\t\t\t\t\t\t\t\t\t[class.hidden]=\"isDisabled()\"\n\t\t\t\t\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'Reorder ' + getBlockLabel(block.blockType) + ' block'\"\n\t\t\t\t\t\t\t\t\t\taria-roledescription=\"sortable\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<ng-icon name=\"heroBars2\" size=\"16\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<mcms-badge>{{ getBlockLabel(block.blockType) }}</mcms-badge>\n\t\t\t\t\t\t\t\t\t<div class=\"flex-1\"></div>\n\t\t\t\t\t\t\t\t\t@if (canRemoveBlock()) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\tmcms-button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"h-7 w-7 text-destructive hover:text-destructive\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"removeBlock(i)\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'Remove ' + getBlockLabel(block.blockType) + ' block'\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<ng-icon name=\"heroTrash\" size=\"14\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"p-4 space-y-3\">\n\t\t\t\t\t\t\t\t\t@for (subField of getBlockFields(block.blockType); track subField.name) {\n\t\t\t\t\t\t\t\t\t\t<mcms-field-renderer\n\t\t\t\t\t\t\t\t\t\t\t[field]=\"subField\"\n\t\t\t\t\t\t\t\t\t\t\t[formNode]=\"getBlockSubNode(i, subField.name)\"\n\t\t\t\t\t\t\t\t\t\t\t[formTree]=\"formTree()\"\n\t\t\t\t\t\t\t\t\t\t\t[formModel]=\"formModel()\"\n\t\t\t\t\t\t\t\t\t\t\t[mode]=\"mode()\"\n\t\t\t\t\t\t\t\t\t\t\t[path]=\"getBlockSubFieldPath(i, subField.name)\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</mcms-card-content>\n\t\t\t@if (canAddBlock()) {\n\t\t\t\t<mcms-card-footer>\n\t\t\t\t\t<div class=\"flex gap-2\">\n\t\t\t\t\t\t@for (blockDef of blockDefinitions(); track blockDef.slug) {\n\t\t\t\t\t\t\t<button mcms-button variant=\"outline\" (click)=\"addBlock(blockDef.slug)\">\n\t\t\t\t\t\t\t\t<ng-icon name=\"heroPlus\" size=\"16\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t{{ blockDef.labels?.singular || blockDef.slug }}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t</mcms-card-footer>\n\t\t\t}\n\t\t</mcms-card>\n\t`,\n})\nexport class BlocksFieldRenderer {\n\t/** Field definition (must be a BlocksField) */\n\treadonly field = input.required<Field>();\n\n\t/** Signal forms FieldTree node for this blocks array */\n\treadonly formNode = input<unknown>(null);\n\n\t/** Root signal forms FieldTree (for layout fields that look up child nodes) */\n\treadonly formTree = input<unknown>(null);\n\n\t/** Form model data (for condition evaluation and relationship filterOptions) */\n\treadonly formModel = input<Record<string, unknown>>({});\n\n\t/** Form mode */\n\treadonly mode = input<EntityFormMode>('create');\n\n\t/** Field path (e.g., \"content\") */\n\treadonly path = input.required<string>();\n\n\t/** Bridge: extract FieldState from formNode */\n\tprivate readonly nodeState = computed(() => getFieldNodeState(this.formNode()));\n\n\t/** Computed label */\n\treadonly label = computed(() => this.field().label || humanizeFieldName(this.field().name));\n\n\t/** Computed description */\n\treadonly description = computed(() => this.field().description || '');\n\n\t/** Block type definitions from the field */\n\treadonly blockDefinitions = computed((): BlockConfig[] => {\n\t\tconst f = this.field();\n\t\tif (f.type === 'blocks') {\n\t\t\treturn f.blocks;\n\t\t}\n\t\treturn [];\n\t});\n\n\t/** Min rows constraint */\n\treadonly minRows = computed((): number => {\n\t\tconst f = this.field();\n\t\treturn f.type === 'blocks' ? (f.minRows ?? 0) : 0;\n\t});\n\n\t/** Max rows constraint */\n\treadonly maxRows = computed((): number | undefined => {\n\t\tconst f = this.field();\n\t\treturn f.type === 'blocks' ? f.maxRows : undefined;\n\t});\n\n\t/** Current blocks as typed items (read from FieldState) */\n\treadonly blocks = computed((): BlockItem[] => {\n\t\tconst state = this.nodeState();\n\t\tif (!state) return [];\n\t\tconst val = state.value();\n\t\tif (Array.isArray(val)) {\n\t\t\treturn val.filter(\n\t\t\t\t(item): item is BlockItem => isRecord(item) && typeof item['blockType'] === 'string',\n\t\t\t);\n\t\t}\n\t\treturn [];\n\t});\n\n\t/**\n\t * Normalize loaded blocks: ensure every block has defaults for all definition fields.\n\t * Blocks saved before new fields were added won't have those keys, and\n\t * signal-forms only creates controls for keys present in the model.\n\t */\n\tprivate readonly _normalizeBlocks = effect(() => {\n\t\tconst state = this.nodeState();\n\t\tif (!state) return;\n\t\tconst val = state.value();\n\t\tif (!Array.isArray(val)) return;\n\n\t\tconst { normalized, changed } = normalizeBlockDefaults(val, this.blockDefMap());\n\t\tif (changed) {\n\t\t\tuntracked(() => state.value.set(normalized));\n\t\t}\n\t});\n\n\t/** Whether the field is disabled (view mode) */\n\treadonly isDisabled = computed(() => this.mode() === 'view');\n\n\t/** Whether a new block can be added */\n\treadonly canAddBlock = computed((): boolean => {\n\t\tif (this.isDisabled()) return false;\n\t\tconst max = this.maxRows();\n\t\treturn max === undefined || this.blocks().length < max;\n\t});\n\n\t/** Whether blocks can be removed */\n\treadonly canRemoveBlock = computed((): boolean => {\n\t\tif (this.isDisabled()) return false;\n\t\treturn this.blocks().length > this.minRows();\n\t});\n\n\t/** Block definition lookup cache */\n\tprivate readonly blockDefMap = computed((): Map<string, BlockConfig> => {\n\t\tconst map = new Map<string, BlockConfig>();\n\t\tfor (const def of this.blockDefinitions()) {\n\t\t\tmap.set(def.slug, def);\n\t\t}\n\t\treturn map;\n\t});\n\n\t/** Get display label for a block type */\n\tgetBlockLabel(blockType: string): string {\n\t\tconst def = this.blockDefMap().get(blockType);\n\t\treturn def?.labels?.singular || blockType;\n\t}\n\n\t/** Get fields for a block type */\n\tgetBlockFields(blockType: string): Field[] {\n\t\tconst def = this.blockDefMap().get(blockType);\n\t\treturn def?.fields.filter((f) => !f.admin?.hidden) ?? [];\n\t}\n\n\t/** Get a FieldTree sub-node for a block's sub-field */\n\tgetBlockSubNode(blockIndex: number, subFieldName: string): unknown {\n\t\tconst blockNode = getSubNode(this.formNode(), blockIndex);\n\t\treturn getSubNode(blockNode, subFieldName);\n\t}\n\n\t/** Get the full path for a block's sub-field */\n\tgetBlockSubFieldPath(blockIndex: number, subFieldName: string): string {\n\t\treturn `${this.path()}.${blockIndex}.${subFieldName}`;\n\t}\n\n\t/** Handle drag-drop reorder */\n\tonDrop(event: CdkDragDrop<unknown>): void {\n\t\tconst state = this.nodeState();\n\t\tif (!state) return;\n\t\tconst blocks = [...this.blocks()];\n\t\tmoveItemInArray(blocks, event.previousIndex, event.currentIndex);\n\t\tstate.value.set(blocks);\n\t}\n\n\t/** Add a new block of the given type */\n\taddBlock(blockType: string): void {\n\t\tconst def = this.blockDefMap().get(blockType);\n\t\tif (!def) return;\n\t\tconst state = this.nodeState();\n\t\tif (!state) return;\n\n\t\tconst newBlock: BlockItem = { blockType };\n\t\tfor (const field of def.fields) {\n\t\t\tnewBlock[field.name] = getFieldDefaultValue(field);\n\t\t}\n\n\t\tconst blocks = [...this.blocks(), newBlock];\n\t\tstate.value.set(blocks);\n\t}\n\n\t/** Remove a block at the given index */\n\tremoveBlock(index: number): void {\n\t\tconst state = this.nodeState();\n\t\tif (!state) return;\n\t\tconst blocks = this.blocks().filter((_, i) => i !== index);\n\t\tstate.value.set(blocks);\n\t}\n}\n"],"names":[],"mappings":"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"}