@vectoriox/iox-builder 1.7.4 → 1.7.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectoriox/iox-builder",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=20.0.0",
6
6
  "@angular/core": ">=20.0.0",
@@ -740,6 +740,77 @@ declare class DragEngineService {
740
740
  static ɵprov: i0.ɵɵInjectableDeclaration<DragEngineService>;
741
741
  }
742
742
 
743
+ /**
744
+ * StyleRegistryService — manages a single <style> tag for the builder canvas.
745
+ *
746
+ * Each builder component gets two CSS classes:
747
+ * .iox-node-{id} — applied to the inner element; handles layout/visual props
748
+ * (display, flex, background, border, padding, etc.)
749
+ * .iox-outer-{id} — applied to the host element by RenderDirective; handles
750
+ * properties that participate in the PARENT flow (margin,
751
+ * align-self, flex-grow/shrink/basis, order).
752
+ *
753
+ * This split is necessary because margin on an inner wrapper only adds internal
754
+ * space — it does not push sibling elements. Applying margin to the host element
755
+ * (which IS the flex/block child in the parent container) makes it work correctly.
756
+ *
757
+ * State styles (hover/active/focus) are stored under key `${nodeId}:${state}`
758
+ * and compiled to `.iox-node-{id}:hover { … }` selectors.
759
+ *
760
+ * Design token variables are stored under the reserved key `__tokens__` and
761
+ * compiled to a `:root { … }` block prepended to all other rules.
762
+ *
763
+ * Scoped to PageUiComponent.providers[] — one stylesheet per builder instance.
764
+ */
765
+ declare class StyleRegistryService {
766
+ readonly changes$: Subject<void>;
767
+ private rules;
768
+ private styleEl;
769
+ /**
770
+ * Properties that must live on the OUTER wrapper (.iox-outer-{id}) because they
771
+ * affect how the element participates in its PARENT layout (flex/block flow).
772
+ * Everything else goes to the INNER element (.iox-node-{id}).
773
+ *
774
+ * Exception — out-of-flow positioning (position:fixed/absolute):
775
+ * When position is fixed or absolute, width is redirected to the inner element
776
+ * (the positioned one) and a default width:100% is added if none is set, so the
777
+ * element stays visible. top/right/bottom/left/zIndex are always inner because
778
+ * they are co-ordinates of the positioned element, not the flow wrapper.
779
+ * position itself goes to inner with `!important` to beat component-scoped CSS.
780
+ */
781
+ private static readonly OUTER_PROPS;
782
+ /** Properties that need !important on the inner element to beat Angular's scoped-CSS specificity boost. */
783
+ private static readonly IMPORTANT_PROPS;
784
+ init(): void;
785
+ /**
786
+ * Write or update the base styles for a node, or a pseudo-class state override.
787
+ *
788
+ * @param nodeId The node's CSS id (used in `.iox-node-{nodeId}`)
789
+ * @param styles Flat CSS property map (camelCase keys)
790
+ * @param state Optional pseudo-class state ('hover' | 'active' | 'focus' | …).
791
+ * When provided, compiles to `.iox-node-{id}:{state} { … }`.
792
+ * State rules are NOT partitioned into inner/outer.
793
+ * @param relativeToId Ancestor css id, required for RELATIONAL states
794
+ * (e.g. 'parent-hover'). Compiles to
795
+ * `.iox-node-{relativeToId}:{base} .iox-node-{nodeId} { … }`.
796
+ */
797
+ upsert(nodeId: string, styles: Record<string, any>, state?: ElementState, relativeToId?: string): void;
798
+ /**
799
+ * Write the org-level design token variables as a `:root { … }` block.
800
+ * Token names should be CSS custom property names without the `--` prefix
801
+ * (e.g., `{ 'iox-primary-color': '#cb9090' }`).
802
+ * Pass an empty object to clear all tokens.
803
+ */
804
+ upsertTokens(tokens: Record<string, string>): void;
805
+ remove(nodeId: string): void;
806
+ destroy(): void;
807
+ private compile;
808
+ private _flushPending;
809
+ private flush;
810
+ static ɵfac: i0.ɵɵFactoryDeclaration<StyleRegistryService, never>;
811
+ static ɵprov: i0.ɵɵInjectableDeclaration<StyleRegistryService>;
812
+ }
813
+
743
814
  /**
744
815
  * MoveableCanvasService — Phase 1 of the Moveable + Selecto migration
745
816
  * (see iox-ai-guidance/architecture/builder/moveable-migration.md).
@@ -757,6 +828,7 @@ declare class DragEngineService {
757
828
  */
758
829
  declare class MoveableCanvasService {
759
830
  private dragEngine;
831
+ private styleRegistry;
760
832
  private moveable;
761
833
  private container;
762
834
  private scaleGetter;
@@ -765,7 +837,9 @@ declare class MoveableCanvasService {
765
837
  private sourceId;
766
838
  /** Called after a successful reorder so the host can emit LAYOUT_CHANGED / refresh selection. */
767
839
  onReorder: (() => void) | null;
768
- constructor(dragEngine: DragEngineService);
840
+ /** Called after a geometry commit (resize) so the host can emit LAYOUT_CHANGED (undo/save). */
841
+ onLayoutChanged: (() => void) | null;
842
+ constructor(dragEngine: DragEngineService, styleRegistry: StyleRegistryService);
769
843
  /** Wire the Moveable control box into `container`; `scaleGetter` returns the live canvas zoom. */
770
844
  init(container: HTMLElement, scaleGetter: () => number): void;
771
845
  /** Point Moveable at the selected element (skips inline-edit + preview-clone targets). */
@@ -776,6 +850,10 @@ declare class MoveableCanvasService {
776
850
  private ensureMoveable;
777
851
  private destroyMoveable;
778
852
  private commitDrag;
853
+ private commitResize;
854
+ /** Write geometry changes into the node's styleTraits (the serialized source of truth) and the
855
+ * central stylesheet, so the style panel, save (self-describing), and SSR engine all agree. */
856
+ private applyStyle;
779
857
  /** Final pointer position from the Moveable end event (client/viewport px). */
780
858
  private lastPointer;
781
859
  /** Walk up from an element to the nearest registered dropzone id (el.id is stamped by DragEngine). */
@@ -1167,77 +1245,6 @@ declare class BuilderComponent implements OnInit, AfterViewInit, OnChanges, OnDe
1167
1245
  static ɵcmp: i0.ɵɵComponentDeclaration<BuilderComponent, "app-builder", never, { "layout": { "alias": "layout"; "required": false; }; "dataSources": { "alias": "dataSources"; "required": false; }; "orgId": { "alias": "orgId"; "required": false; }; "routeParams": { "alias": "routeParams"; "required": false; }; "pageName": { "alias": "pageName"; "required": false; }; "isSaving": { "alias": "isSaving"; "required": false; }; "pageStatus": { "alias": "pageStatus"; "required": false; }; "pageSettings": { "alias": "pageSettings"; "required": false; }; "globalElements": { "alias": "globalElements"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "moveableMode": { "alias": "moveableMode"; "required": false; }; }, { "save": "save"; "undo": "undo"; "redo": "redo"; "back": "back"; "preview": "preview"; "publishToggle": "publishToggle"; "pageSettingsChange": "pageSettingsChange"; "applyAnimationToAll": "applyAnimationToAll"; "saveBlock": "saveBlock"; "globalElementsChange": "globalElementsChange"; }, never, ["[builderComponents]", "[builderTokens]", "[builderPanel]"], false, never>;
1168
1246
  }
1169
1247
 
1170
- /**
1171
- * StyleRegistryService — manages a single <style> tag for the builder canvas.
1172
- *
1173
- * Each builder component gets two CSS classes:
1174
- * .iox-node-{id} — applied to the inner element; handles layout/visual props
1175
- * (display, flex, background, border, padding, etc.)
1176
- * .iox-outer-{id} — applied to the host element by RenderDirective; handles
1177
- * properties that participate in the PARENT flow (margin,
1178
- * align-self, flex-grow/shrink/basis, order).
1179
- *
1180
- * This split is necessary because margin on an inner wrapper only adds internal
1181
- * space — it does not push sibling elements. Applying margin to the host element
1182
- * (which IS the flex/block child in the parent container) makes it work correctly.
1183
- *
1184
- * State styles (hover/active/focus) are stored under key `${nodeId}:${state}`
1185
- * and compiled to `.iox-node-{id}:hover { … }` selectors.
1186
- *
1187
- * Design token variables are stored under the reserved key `__tokens__` and
1188
- * compiled to a `:root { … }` block prepended to all other rules.
1189
- *
1190
- * Scoped to PageUiComponent.providers[] — one stylesheet per builder instance.
1191
- */
1192
- declare class StyleRegistryService {
1193
- readonly changes$: Subject<void>;
1194
- private rules;
1195
- private styleEl;
1196
- /**
1197
- * Properties that must live on the OUTER wrapper (.iox-outer-{id}) because they
1198
- * affect how the element participates in its PARENT layout (flex/block flow).
1199
- * Everything else goes to the INNER element (.iox-node-{id}).
1200
- *
1201
- * Exception — out-of-flow positioning (position:fixed/absolute):
1202
- * When position is fixed or absolute, width is redirected to the inner element
1203
- * (the positioned one) and a default width:100% is added if none is set, so the
1204
- * element stays visible. top/right/bottom/left/zIndex are always inner because
1205
- * they are co-ordinates of the positioned element, not the flow wrapper.
1206
- * position itself goes to inner with `!important` to beat component-scoped CSS.
1207
- */
1208
- private static readonly OUTER_PROPS;
1209
- /** Properties that need !important on the inner element to beat Angular's scoped-CSS specificity boost. */
1210
- private static readonly IMPORTANT_PROPS;
1211
- init(): void;
1212
- /**
1213
- * Write or update the base styles for a node, or a pseudo-class state override.
1214
- *
1215
- * @param nodeId The node's CSS id (used in `.iox-node-{nodeId}`)
1216
- * @param styles Flat CSS property map (camelCase keys)
1217
- * @param state Optional pseudo-class state ('hover' | 'active' | 'focus' | …).
1218
- * When provided, compiles to `.iox-node-{id}:{state} { … }`.
1219
- * State rules are NOT partitioned into inner/outer.
1220
- * @param relativeToId Ancestor css id, required for RELATIONAL states
1221
- * (e.g. 'parent-hover'). Compiles to
1222
- * `.iox-node-{relativeToId}:{base} .iox-node-{nodeId} { … }`.
1223
- */
1224
- upsert(nodeId: string, styles: Record<string, any>, state?: ElementState, relativeToId?: string): void;
1225
- /**
1226
- * Write the org-level design token variables as a `:root { … }` block.
1227
- * Token names should be CSS custom property names without the `--` prefix
1228
- * (e.g., `{ 'iox-primary-color': '#cb9090' }`).
1229
- * Pass an empty object to clear all tokens.
1230
- */
1231
- upsertTokens(tokens: Record<string, string>): void;
1232
- remove(nodeId: string): void;
1233
- destroy(): void;
1234
- private compile;
1235
- private _flushPending;
1236
- private flush;
1237
- static ɵfac: i0.ɵɵFactoryDeclaration<StyleRegistryService, never>;
1238
- static ɵprov: i0.ɵɵInjectableDeclaration<StyleRegistryService>;
1239
- }
1240
-
1241
1248
  /**
1242
1249
  * RenderDirective — applied to <ng-container> to dynamically instantiate a
1243
1250
  * builder component with zero wrapper elements in the DOM.