@vectoriox/iox-builder 4.18.3 → 4.20.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.
@@ -16,7 +16,7 @@ import { SelectModule } from 'primeng/select';
16
16
  import { TooltipModule } from 'primeng/tooltip';
17
17
  import { DialogModule } from 'primeng/dialog';
18
18
  import * as i18 from '@vectoriox/iox-ui';
19
- import { DEFAULT_WIDTH_BY_TYPE, Breakpoint, BREAKPOINTS, countOverrides, setOverride, breakpointDef, breakpointForWidth, FormRenderState, safeSetInput, ContextStore, ComponentInstanceRegistryService, isActionEnabled, isContextAction, contextActionEffect, resolveContextValue, DeclarationContext, planResponsiveRules, resolveStyleProps, buildTargetedStateSelector, compileDeclarations, wrapInBreakpointQuery, BreakpointQueryKind, composeVirtualTraits, stateNamesIn, resolveInputs, setInputOverride, collectContextSlotKeys, withContextSlots, compilePageStyle, nodeUsesContext, resolveBoundValue, IS_PREVIEW, planDataSource, dataSourcePlanToRequest, normalizeCollectionResult, resolveRepeaterItems, getByPath, computeRelative, IoxPageModule } from '@vectoriox/iox-ui';
19
+ import { DEFAULT_WIDTH_BY_TYPE, Breakpoint, BREAKPOINTS, countOverrides, setOverride, breakpointDef, breakpointForWidth, FormRenderState, safeSetInput, ContextStore, ComponentInstanceRegistryService, isActionEnabled, isContextAction, contextActionEffect, resolveContextValue, DeclarationContext, buildPartSelector, planResponsiveRules, resolveStyleProps, buildTargetedStateSelector, compileDeclarations, wrapInBreakpointQuery, BreakpointQueryKind, composeVirtualTraits, stateNamesIn, resolveInputs, setInputOverride, collectContextSlotKeys, withContextSlots, compilePageStyle, nodeUsesContext, resolveBoundValue, IS_PREVIEW, planDataSource, dataSourcePlanToRequest, normalizeCollectionResult, resolveRepeaterItems, getByPath, computeRelative, IoxPageModule } from '@vectoriox/iox-ui';
20
20
  export { ComponentInstanceRegistryService, VIRTUAL_TRAIT_KEYS, composeVirtualTraits } from '@vectoriox/iox-ui';
21
21
  import Lenis from 'lenis';
22
22
  import { Subject, BehaviorSubject, of, forkJoin } from 'rxjs';
@@ -139,7 +139,20 @@ const TARGETED_STATES = ['trigger-hover'];
139
139
  const TARGETED_STATE_BASE = {
140
140
  'trigger-hover': 'hover',
141
141
  };
142
- const SUPPORTED_STATES = [...INTERACTION_STATES, ...STRUCTURAL_STATES, ...RELATIONAL_STATES, ...TARGETED_STATES];
142
+ /**
143
+ * Design-time validation states (forms-and-inputs-plan.md Part 2, board 7 — "the failure
144
+ * design"). Not real CSS pseudo-classes: `IoxFieldComponent` already carries `.iox-invalid`/
145
+ * `.iox-valid` host classes it sets from `forceInvalid`/`showValid` (decision D5), so authoring
146
+ * "Wrong"/"Accepted" styles compiles to a CLASS-compound selector, not `:state`. Currently only
147
+ * meaningful on Field (or any future component with the same host classes).
148
+ */
149
+ const VALIDATION_STATES = ['wrong', 'accepted'];
150
+ /** The host class each validation state maps to. */
151
+ const VALIDATION_STATE_CLASS = {
152
+ wrong: 'iox-invalid',
153
+ accepted: 'iox-valid',
154
+ };
155
+ const SUPPORTED_STATES = [...INTERACTION_STATES, ...STRUCTURAL_STATES, ...RELATIONAL_STATES, ...TARGETED_STATES, ...VALIDATION_STATES];
143
156
  /**
144
157
  * Build a full StyleTraitGroup[] schema populated with values from a flat
145
158
  * styleProps map. Used when editing a preset in the Style panel — the panel
@@ -872,6 +885,13 @@ var PanelEventTypes;
872
885
  * would (`string` component type, or a block / symbol object). The builder resolves WHERE from
873
886
  * the current selection — see `resolveInsertTarget`. */
874
887
  PanelEventTypes["INSERT_COMPONENT"] = "insertcomponent";
888
+ /** A panel wants to select a NODE it already has a reference to (e.g. the Form's nested field
889
+ * list). Carries `{ node }`. `OverlayService.setSelect()` alone only updates the overlay's own
890
+ * visual state — `selectedItem`/`selectedPath` (breadcrumb) and every other panel's idea of
891
+ * "what's selected" stay stale unless the SAME `_emitElementSelect` a real canvas click goes
892
+ * through also runs. This event is that path for code outside `BuilderComponent` itself,
893
+ * mirroring what `onTreeNodeSelect`/`onCrumbSelect` already do internally. */
894
+ PanelEventTypes["SELECT_NODE"] = "selectnode";
875
895
  })(PanelEventTypes || (PanelEventTypes = {}));
876
896
  class PanelEventService {
877
897
  constructor() {
@@ -3612,6 +3632,28 @@ class StyleRegistryService {
3612
3632
  this.rules.delete(nodeId);
3613
3633
  this.flush();
3614
3634
  }
3635
+ /**
3636
+ * Write or clear the styles for one PART of a compound component (board 7 — "the failure
3637
+ * design"), optionally further scoped to a validation state ('wrong'/'accepted'). Compiles
3638
+ * through the exact same `compile()` every other rule uses — `buildPartSelector` (shared,
3639
+ * `@vectoriox/iox-ui`) just builds a different selector string. Unlike interaction/relational/
3640
+ * targeted states, a validation state compounds a CLASS onto the node (`.iox-invalid`), not a
3641
+ * `:pseudo-class`, since `IoxFieldComponent` sets that class itself from `forceInvalid`/
3642
+ * `showValid` — there is no real "wrong" pseudo-class to hook.
3643
+ */
3644
+ upsertPart(nodeId, partClassName, styles, state) {
3645
+ if (!nodeId || !partClassName)
3646
+ return;
3647
+ const key = `${nodeId}:part:${partClassName}${state ? ':' + state : ''}`;
3648
+ const validationClass = state ? VALIDATION_STATE_CLASS[state] : undefined;
3649
+ const selector = buildPartSelector(nodeId, partClassName, validationClass);
3650
+ const css = Object.keys(styles).length ? this.compile(selector, styles) : '';
3651
+ if (css)
3652
+ this.rules.set(key, css);
3653
+ else
3654
+ this.rules.delete(key);
3655
+ this.flush();
3656
+ }
3615
3657
  /**
3616
3658
  * Emit (or clear) a node's breakpoint rules. `planResponsiveRules` — shared with the SSR engine —
3617
3659
  * decides what each breakpoint emits; this only turns it into selectors, through the SAME
@@ -4268,6 +4310,9 @@ const CONTAINER_TAGS = ['div', 'section', 'article', 'header', 'footer', 'main',
4268
4310
  * </ng-container>
4269
4311
  */
4270
4312
  class RenderDirective {
4313
+ /** type -> its declared parts (board 7), cached so partClassNameFor doesn't instantiate a
4314
+ * fresh ComponentConfig on every render — same precedent as the layer tree's own icon cache. */
4315
+ static { this.partsCache = new Map(); }
4271
4316
  constructor(vcr, injector, envInjector, doc, registryService, overlayService, styleRegistry, interactionEngine, cdr, panelEventService, dragEngine) {
4272
4317
  this.vcr = vcr;
4273
4318
  this.injector = injector;
@@ -4355,6 +4400,19 @@ class RenderDirective {
4355
4400
  * registry — at state-restore time the parent isn't registered yet, since it registers only
4356
4401
  * AFTER rendering its children). Used to key relational (parent-hover) rules. (issue #1)
4357
4402
  */
4403
+ /** The stable class a declared part compiles against, e.g. ('Field', 'error') -> 'iox-field__error'.
4404
+ * Undefined when the type declares no such part (or no parts at all) — caller skips it. */
4405
+ partClassNameFor(type, partKey) {
4406
+ let byKey = RenderDirective.partsCache.get(type);
4407
+ if (!byKey) {
4408
+ const config = this.registryService.createConfig(type);
4409
+ byKey = {};
4410
+ for (const part of config?.parts ?? [])
4411
+ byKey[part.key] = part.className;
4412
+ RenderDirective.partsCache.set(type, byKey);
4413
+ }
4414
+ return byKey[partKey];
4415
+ }
4358
4416
  resolveParentNodeId(childEl) {
4359
4417
  let el = childEl?.parentElement ?? null;
4360
4418
  while (el) {
@@ -4504,6 +4562,22 @@ class RenderDirective {
4504
4562
  }
4505
4563
  // Breakpoint layers — AFTER the state loop, so every scope resolved above is recorded.
4506
4564
  this.styleRegistry.upsertResponsive(cssId, initialStyle, node.stateStyles, node.responsive);
4565
+ // Part styles (board 7 — "the failure design"). Simpler than the state loop above:
4566
+ // a part+state combo always compounds onto THIS node (no relational/targeted scope
4567
+ // to resolve), so every entry just needs its base plus each of its own state overrides.
4568
+ const partStyles = node.partStyles;
4569
+ if (partStyles) {
4570
+ for (const [partKey, part] of Object.entries(partStyles)) {
4571
+ const className = this.partClassNameFor(node.type, partKey);
4572
+ if (!className)
4573
+ continue;
4574
+ const base = part.styleProps ?? {};
4575
+ this.styleRegistry.upsertPart(cssId, className, composeVirtualTraits(base));
4576
+ for (const [state, stateMap] of Object.entries(part.stateStyles ?? {})) {
4577
+ this.styleRegistry.upsertPart(cssId, className, composeVirtualTraits(stateMap, base), state);
4578
+ }
4579
+ }
4580
+ }
4507
4581
  }
4508
4582
  // Set nodeId — declared as @Input() on every builder component.
4509
4583
  if (cssId) {
@@ -7077,6 +7151,19 @@ class BuilderComponent {
7077
7151
  this.insertFromPanel(panelEvent.data);
7078
7152
  return;
7079
7153
  }
7154
+ // A panel (e.g. the Form's nested field list) wants to select a node it already holds a
7155
+ // reference to — same path onTreeNodeSelect/onCrumbSelect use, so selectedItem/selectedPath
7156
+ // and every panel stay in sync, not just the overlay's own visual selection box.
7157
+ if (panelEvent.type === PanelEventTypes.SELECT_NODE) {
7158
+ const node = panelEvent.data?.node;
7159
+ const ref = node ? this.overlayService.getNodeRef(node) : undefined;
7160
+ if (node && ref) {
7161
+ this.selectedItem = node;
7162
+ this.overlayService.setSelect(ref.element, node.type, this.activeMode, node, ref.componentRef);
7163
+ this._emitElementSelect(node, ref.componentRef);
7164
+ }
7165
+ return;
7166
+ }
7080
7167
  // Every style or structural edit — including a breakpoint override — emits LAYOUT_CHANGED.
7081
7168
  if (panelEvent.type === PanelEventTypes.LAYOUT_CHANGED) {
7082
7169
  this.refreshBreakpointCounts();
@@ -9715,6 +9802,20 @@ class GalleryConfig extends ComponentConfig {
9715
9802
  }
9716
9803
  }
9717
9804
 
9805
+ /**
9806
+ * Field's styleable sub-elements (board 7 — "the failure design"). Class names match
9807
+ * `IoxFieldComponent`'s own template exactly (`@vectoriox/iox-ui`) — the part mechanism styles
9808
+ * what that component already renders, it does not invent new markup. "Whole field" (the node's
9809
+ * own base styling) is not listed here — the Style panel always offers it as the implicit first
9810
+ * choice, falling back to the node's ordinary `styleTraits`.
9811
+ */
9812
+ const FIELD_PARTS = [
9813
+ { key: 'label', label: 'Label', className: 'iox-field__label' },
9814
+ { key: 'control', label: 'The box', className: 'iox-field__control' },
9815
+ { key: 'help', label: 'Note', className: 'iox-field__help' },
9816
+ { key: 'error', label: 'Error message', className: 'iox-field__error' },
9817
+ { key: 'required', label: 'Required mark', className: 'iox-field__required' },
9818
+ ];
9718
9819
  /** Every style group — the state blocks and field group are ordinary containers to style. */
9719
9820
  const fullStyles = () => buildFullStyleTraits();
9720
9821
  /** Layout-ish groups for a form shell: it arranges fields, it is not text. */
@@ -9795,6 +9896,7 @@ class FormComponentConfig extends ComponentConfig {
9795
9896
  class FieldComponentConfig extends ComponentConfig {
9796
9897
  constructor() {
9797
9898
  super('Field', 'iox-field', 'ph-thin ph-text-box', 'Forms');
9899
+ this.parts = FIELD_PARTS;
9798
9900
  this.traits = [
9799
9901
  new TraitConfig('__contentLabel', 'Content', TraitInputType.SectionLabel),
9800
9902
  new TraitConfig('label', 'Label', TraitInputType.Text, undefined, 'Label'),
@@ -10349,5 +10451,5 @@ class BuilderSpacerComponentConfig extends ComponentConfig {
10349
10451
  * Generated bundle index. Do not edit.
10350
10452
  */
10351
10453
 
10352
- export { ACTION_TYPE_OPTIONS, AuditCode, AuditPanelComponent, AuditSeverity, BODY_CRUMB_LABEL, BREAKPOINT_PRESENTATION, BUILDER_CANVAS_CONTAINER, BUILDER_CHROME_EN, BackgroundGroupStyleConfig, BorderGroupStyleConfig, BreadcrumbBarComponent, BuilderButtonBlockComponent, BuilderButtonComponentConfig, BuilderClipboardService, BuilderComponent, BuilderContainerComponent, BuilderContainerComponentConfig, BuilderDataSourceService, BuilderDividerComponentConfig, BuilderHeadingComponentConfig, BuilderHistoryService, BuilderIconComponentConfig, BuilderImageComponentConfig, BuilderLinkComponentConfig, BuilderLinkedContainerComponent, BuilderLinkedContainerConfig, BuilderListComponentConfig, BuilderListItemComponentConfig, BuilderMode, BuilderRepeaterComponent, BuilderSpacerComponentConfig, ButtonBlockComponentConfig, CardComponentConfig, ChildLayoutGroupStyleConfig, ComponentConfig, ComponentRegistryService, DEFAULT_ESSENTIAL_TRAITS, DRAG_HANDLE_ATTR, DataSourceRegistryService, DataSourceType, DimensionsGroupStyleConfig, DragEngineService, EASING_OPTIONS$1 as EASING_OPTIONS, ESSENTIAL_TRAITS_BY_TYPE, EffectsGroupStyleConfig, FORM_PRESETS, FORM_TYPE, FieldComponentConfig, FieldGroupComponentConfig, FormComponentConfig, FormErrorComponentConfig, FormStateService, FormSuccessComponentConfig, GalleryConfig, GroupStyleConfig, INTERACTION_STATES, INVERSE_ACTION, IOX_BUILDER_LABELS, IOX_DATA_SOURCE_ENDPOINTS, IOX_FONT_MANAGER, InteractionEngineService, InteractionPresetRegistryService, IoxBuilderModule, IoxDraggableDirective, IoxDropzoneDirective, LAYOUT_PRESETS, LayerTreeComponent, LayoutGroupStyleConfig, ListGroupStyleConfig, NodeAction, OverlayComponent, OverlayService, PanelChildComponent, PanelComponent, PanelEventService, PanelEventTypes, PanelTypes, PositionGroupStyleConfig, PresetRegistryService, RELATIONAL_STATES, RELATIONAL_STATE_BASE, ROUTE_ANIMATION_OPTIONS, RenderDirective, RepeaterComponentConfig, SCREEN_WIDTH_OPTIONS, STRUCTURAL_STATES, SUPPORTED_STATES, SectionComponent, SectionComponentConfig, SizeGroupStyleConfig, SliderContainerComponent, SliderContainerConfig, SliderSlideComponent, SliderSlideConfig, SpacingGroupStyleConfig, StyleCategory, StyleRegistryService, TraitConfig as StyleTraitConfig, SubmitButtonComponentConfig, SymbolRegistryService, TARGETED_STATES, TARGETED_STATE_BASE, TRIGGER_OPTIONS, TextBlockComponentConfig, ToolbarAction, ToolbarComponent, TraitConfig, TraitInputType, TypographyGroupStyleConfig, UNITS_ALL, UNITS_DEG, UNITS_FIXED, UNITS_NO_VW, ViewportService, ZOOM_OPTIONS, arrayItemSchemaFields, arraySchemaFields, auditNodes, buildFormPreset, buildFullStyleTraits, buildLayoutPreset, buildPresetStyleTraits, canFluidise, collapseColumnsProps, columnCountOf, defaultBuilderLabels, defaultPageSettings, dropTargetLabel, essentialTraitsFor, findNodeLocation, findParentOf, flattenSchemaFields, fluidiseProps, generateNodeId, isHiddenAt, matchesControlSearch, nearestFormNode, nodeAncestorPath, nodeAncestorPathInEither, reorderProps, resolveInsertTarget, resolveTraitControllerType, resolveTraitOptions, setStyleTrait, stackChildrenProps, summarise, visibilityProps, wrapNode };
10454
+ export { ACTION_TYPE_OPTIONS, AuditCode, AuditPanelComponent, AuditSeverity, BODY_CRUMB_LABEL, BREAKPOINT_PRESENTATION, BUILDER_CANVAS_CONTAINER, BUILDER_CHROME_EN, BackgroundGroupStyleConfig, BorderGroupStyleConfig, BreadcrumbBarComponent, BuilderButtonBlockComponent, BuilderButtonComponentConfig, BuilderClipboardService, BuilderComponent, BuilderContainerComponent, BuilderContainerComponentConfig, BuilderDataSourceService, BuilderDividerComponentConfig, BuilderHeadingComponentConfig, BuilderHistoryService, BuilderIconComponentConfig, BuilderImageComponentConfig, BuilderLinkComponentConfig, BuilderLinkedContainerComponent, BuilderLinkedContainerConfig, BuilderListComponentConfig, BuilderListItemComponentConfig, BuilderMode, BuilderRepeaterComponent, BuilderSpacerComponentConfig, ButtonBlockComponentConfig, CardComponentConfig, ChildLayoutGroupStyleConfig, ComponentConfig, ComponentRegistryService, DEFAULT_ESSENTIAL_TRAITS, DRAG_HANDLE_ATTR, DataSourceRegistryService, DataSourceType, DimensionsGroupStyleConfig, DragEngineService, EASING_OPTIONS$1 as EASING_OPTIONS, ESSENTIAL_TRAITS_BY_TYPE, EffectsGroupStyleConfig, FIELD_PARTS, FORM_PRESETS, FORM_TYPE, FieldComponentConfig, FieldGroupComponentConfig, FormComponentConfig, FormErrorComponentConfig, FormStateService, FormSuccessComponentConfig, GalleryConfig, GroupStyleConfig, INTERACTION_STATES, INVERSE_ACTION, IOX_BUILDER_LABELS, IOX_DATA_SOURCE_ENDPOINTS, IOX_FONT_MANAGER, InteractionEngineService, InteractionPresetRegistryService, IoxBuilderModule, IoxDraggableDirective, IoxDropzoneDirective, LAYOUT_PRESETS, LayerTreeComponent, LayoutGroupStyleConfig, ListGroupStyleConfig, NodeAction, OverlayComponent, OverlayService, PanelChildComponent, PanelComponent, PanelEventService, PanelEventTypes, PanelTypes, PositionGroupStyleConfig, PresetRegistryService, RELATIONAL_STATES, RELATIONAL_STATE_BASE, ROUTE_ANIMATION_OPTIONS, RenderDirective, RepeaterComponentConfig, SCREEN_WIDTH_OPTIONS, STRUCTURAL_STATES, SUPPORTED_STATES, SectionComponent, SectionComponentConfig, SizeGroupStyleConfig, SliderContainerComponent, SliderContainerConfig, SliderSlideComponent, SliderSlideConfig, SpacingGroupStyleConfig, StyleCategory, StyleRegistryService, TraitConfig as StyleTraitConfig, SubmitButtonComponentConfig, SymbolRegistryService, TARGETED_STATES, TARGETED_STATE_BASE, TRIGGER_OPTIONS, TextBlockComponentConfig, ToolbarAction, ToolbarComponent, TraitConfig, TraitInputType, TypographyGroupStyleConfig, UNITS_ALL, UNITS_DEG, UNITS_FIXED, UNITS_NO_VW, VALIDATION_STATES, VALIDATION_STATE_CLASS, ViewportService, ZOOM_OPTIONS, arrayItemSchemaFields, arraySchemaFields, auditNodes, buildFormPreset, buildFullStyleTraits, buildLayoutPreset, buildPresetStyleTraits, canFluidise, collapseColumnsProps, columnCountOf, defaultBuilderLabels, defaultPageSettings, dropTargetLabel, essentialTraitsFor, findNodeLocation, findParentOf, flattenSchemaFields, fluidiseProps, generateNodeId, isHiddenAt, matchesControlSearch, nearestFormNode, nodeAncestorPath, nodeAncestorPathInEither, reorderProps, resolveInsertTarget, resolveTraitControllerType, resolveTraitOptions, setStyleTrait, stackChildrenProps, summarise, visibilityProps, wrapNode };
10353
10455
  //# sourceMappingURL=vectoriox-iox-builder.mjs.map