@vectoriox/iox-builder 5.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, inject, NgZone, EventEmitter, createComponent, Output, Input, Inject, Directive, ChangeDetectionStrategy, Component,
|
|
2
|
+
import { Injectable, inject, NgZone, InjectionToken, EventEmitter, createComponent, Output, Input, Inject, Directive, ChangeDetectionStrategy, Component, ViewChild, effect, Optional, ContentChildren, NO_ERRORS_SCHEMA, NgModule } from '@angular/core';
|
|
3
3
|
import * as i2 from '@angular/common';
|
|
4
4
|
import { DOCUMENT, CommonModule } from '@angular/common';
|
|
5
5
|
import * as i16 from '@angular/forms';
|
|
@@ -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 i1 from '@vectoriox/iox-ui';
|
|
19
|
-
import { VALIDATION_STATES as VALIDATION_STATES$1, VALIDATION_STATE_CLASS as VALIDATION_STATE_CLASS$1, DEFAULT_WIDTH_BY_TYPE, Breakpoint, BREAKPOINTS, countOverrides, setOverride, defaultElementStyleFor, applyElementStyle, stripSuppressedProps, DeclarationContext, buildPartSelector, planResponsiveRules, resolveStyleProps, buildTargetedStateSelector, statePseudoClass, compileTokenCssBlocks, compileDeclarations, wrapInBreakpointQuery, BreakpointQueryKind, breakpointDef, breakpointForWidth, FormRenderState, safeSetInput, ContextStore, ComponentInstanceRegistryService, isActionEnabled, isContextAction, contextActionEffect, resolveContextValue, composeVirtualTraits, stateNamesIn, partClassName,
|
|
19
|
+
import { VALIDATION_STATES as VALIDATION_STATES$1, VALIDATION_STATE_CLASS as VALIDATION_STATE_CLASS$1, DEFAULT_WIDTH_BY_TYPE, COLOR_SCHEME_TRAIT, COLOR_SCHEMES, ColorScheme, Breakpoint, BREAKPOINTS, countOverrides, setOverride, defaultElementStyleFor, applyElementStyle, stripSuppressedProps, DeclarationContext, buildPartSelector, planResponsiveRules, resolveStyleProps, buildTargetedStateSelector, statePseudoClass, compileTokenCssBlocks, compileDeclarations, wrapInBreakpointQuery, BreakpointQueryKind, breakpointDef, breakpointForWidth, FormRenderState, safeSetInput, ContextStore, ComponentInstanceRegistryService, isActionEnabled, isContextAction, contextActionEffect, resolveContextValue, IS_PREVIEW, emptyImageSrc, composeVirtualTraits, withDefaultHoverTransition, stateNamesIn, partClassName, syncNodeDesignClasses, resolveInputs, setInputOverride, collectContextSlotKeys, withContextSlots, compilePageStyle, nodeUsesContext, resolveBoundValue, planDataSource, dataSourcePlanToRequest, normalizeCollectionResult, resolveRepeaterItems, getByPath, computeRelative, IoxPageModule, PALETTE_PRESETS, PART_CLASS_NAMES } 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';
|
|
@@ -655,6 +655,15 @@ class ListGroupStyleConfig extends GroupStyleConfig {
|
|
|
655
655
|
* Every call produces new TraitConfig instances so different component nodes
|
|
656
656
|
* never share mutable state.
|
|
657
657
|
*/
|
|
658
|
+
/**
|
|
659
|
+
* The section colour scheme (design-system §3c) — a CONTENT trait, stored in `props` and saved with
|
|
660
|
+
* the page, never a style prop: it becomes the class `iox-scheme-<id>` (the shared
|
|
661
|
+
* `nodeDesignClasses`) where the token sheet re-declares the section's tokens. Edited in the Style
|
|
662
|
+
* panel beside the element style; the Bindings panel does not list it.
|
|
663
|
+
*/
|
|
664
|
+
function buildColorSchemeTrait() {
|
|
665
|
+
return new TraitConfig(COLOR_SCHEME_TRAIT, 'Section colours', TraitInputType.Select, COLOR_SCHEMES.map(s => ({ label: s.label, value: s.id })), ColorScheme.Default);
|
|
666
|
+
}
|
|
658
667
|
function buildFullStyleTraits() {
|
|
659
668
|
return [
|
|
660
669
|
new PositionGroupStyleConfig(),
|
|
@@ -1559,9 +1568,7 @@ class ComponentRegistryService {
|
|
|
1559
1568
|
const config = this.createBaseConfig(type);
|
|
1560
1569
|
if (!config)
|
|
1561
1570
|
return null;
|
|
1562
|
-
|
|
1563
|
-
if (id)
|
|
1564
|
-
applyElementStyle(config, id);
|
|
1571
|
+
wearDefaultStyles(config);
|
|
1565
1572
|
return config;
|
|
1566
1573
|
}
|
|
1567
1574
|
/**
|
|
@@ -1594,6 +1601,16 @@ class ComponentRegistryService {
|
|
|
1594
1601
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: ComponentRegistryService, decorators: [{
|
|
1595
1602
|
type: Injectable
|
|
1596
1603
|
}] });
|
|
1604
|
+
/** A new node AND the default children its config builds (a palette Form's fields, submit and
|
|
1605
|
+
* notices) are all new elements: each wears its type's default style. */
|
|
1606
|
+
function wearDefaultStyles(node) {
|
|
1607
|
+
const id = defaultElementStyleFor(node.type, traitValues(node));
|
|
1608
|
+
if (id)
|
|
1609
|
+
applyElementStyle(node, id);
|
|
1610
|
+
for (const child of node.children ?? [])
|
|
1611
|
+
if (child?.type)
|
|
1612
|
+
wearDefaultStyles(child);
|
|
1613
|
+
}
|
|
1597
1614
|
function traitValues(config) {
|
|
1598
1615
|
const out = {};
|
|
1599
1616
|
for (const trait of config.traits ?? [])
|
|
@@ -4487,6 +4504,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImpo
|
|
|
4487
4504
|
args: [{ providedIn: 'root' }]
|
|
4488
4505
|
}] });
|
|
4489
4506
|
|
|
4507
|
+
/**
|
|
4508
|
+
* Canvas data preview used to come from host-provided content services (IOX_CONTENT_SERVICE /
|
|
4509
|
+
* IOX_SHOP_SERVICE), whose `getContent(contentType, orgId)` hit the ADMIN resources endpoint and
|
|
4510
|
+
* accepted no filters — so the Repeater/Slider ignored every data-source filter. Data now flows
|
|
4511
|
+
* through BuilderDataSourceService + the shared planDataSource, configured with
|
|
4512
|
+
* IOX_DATA_SOURCE_ENDPOINTS. Those tokens are gone; do not reintroduce a fetch that bypasses it.
|
|
4513
|
+
*/
|
|
4514
|
+
/** Optional font manager. Provide from the host app to populate the fontFamily dropdown. */
|
|
4515
|
+
const IOX_FONT_MANAGER = new InjectionToken('IOX_FONT_MANAGER');
|
|
4516
|
+
/**
|
|
4517
|
+
* Translates the builder library's OWN chrome.
|
|
4518
|
+
*
|
|
4519
|
+
* The library cannot depend on ngx-translate — that is the host app's choice — but its toolbar was
|
|
4520
|
+
* hardcoded English, which shows through as untranslated controls in a Hebrew/RTL admin. This token
|
|
4521
|
+
* lets the host route those strings through its own i18n while the library keeps working standalone:
|
|
4522
|
+
* unprovided, `defaultBuilderLabels` returns the English text, so nothing ever renders a raw key.
|
|
4523
|
+
*
|
|
4524
|
+
* Keys are namespaced `builder.chrome.*` and listed in `BUILDER_CHROME_EN` below — that object is
|
|
4525
|
+
* the contract. A host providing this token should add those keys to its own bundles.
|
|
4526
|
+
*/
|
|
4527
|
+
const IOX_BUILDER_LABELS = new InjectionToken('IOX_BUILDER_LABELS', {
|
|
4528
|
+
providedIn: 'root',
|
|
4529
|
+
factory: () => defaultBuilderLabels,
|
|
4530
|
+
});
|
|
4531
|
+
/** Standalone behaviour: the English text the library ships with. */
|
|
4532
|
+
const defaultBuilderLabels = (_key, fallback) => fallback;
|
|
4533
|
+
/**
|
|
4534
|
+
* Every user-visible string in the builder's own chrome, so a host can copy this into its bundles
|
|
4535
|
+
* in one go rather than discovering keys one missing label at a time.
|
|
4536
|
+
*/
|
|
4537
|
+
const BUILDER_CHROME_EN = Object.freeze({
|
|
4538
|
+
'builder.chrome.select': 'Select',
|
|
4539
|
+
'builder.chrome.pan': 'Pan',
|
|
4540
|
+
'builder.chrome.style': 'Style',
|
|
4541
|
+
'builder.chrome.publish': 'Publish',
|
|
4542
|
+
'builder.chrome.unpublish': 'Unpublish',
|
|
4543
|
+
'builder.chrome.breakpoint': 'Breakpoint',
|
|
4544
|
+
'builder.chrome.screenWidth': 'Screen width',
|
|
4545
|
+
'builder.chrome.zoom': 'Zoom',
|
|
4546
|
+
'builder.chrome.audit': 'Responsive audit',
|
|
4547
|
+
'builder.chrome.auditHint': 'Responsive audit — what is broken at this width',
|
|
4548
|
+
'builder.chrome.undo': 'Undo',
|
|
4549
|
+
'builder.chrome.redo': 'Redo',
|
|
4550
|
+
'builder.chrome.save': 'Save',
|
|
4551
|
+
'builder.chrome.preview': 'Preview',
|
|
4552
|
+
'builder.chrome.addImage': 'Add image',
|
|
4553
|
+
});
|
|
4554
|
+
|
|
4490
4555
|
// Module-level counter — unique drop-list ID per Section instance across the whole app session.
|
|
4491
4556
|
let dropListCounter = 0;
|
|
4492
4557
|
/**
|
|
@@ -4549,6 +4614,8 @@ class RenderDirective {
|
|
|
4549
4614
|
this.onMouseEnter = new EventEmitter();
|
|
4550
4615
|
this.onMouseLeave = new EventEmitter();
|
|
4551
4616
|
this.childSubs = [];
|
|
4617
|
+
this.isPreview = inject(IS_PREVIEW, { optional: true }) ?? false;
|
|
4618
|
+
this.labels = inject(IOX_BUILDER_LABELS);
|
|
4552
4619
|
/** Host element drag was registered on (collapsed path) — unregistered on destroy. */
|
|
4553
4620
|
this.hostDragEl = null;
|
|
4554
4621
|
}
|
|
@@ -4697,6 +4764,14 @@ class RenderDirective {
|
|
|
4697
4764
|
// safeSetInput for every component that does not declare it.
|
|
4698
4765
|
if (node.responsive)
|
|
4699
4766
|
safeSetInput(componentRef, 'responsive', node.responsive);
|
|
4767
|
+
// Empty images (DS3): a MARKED Image with no source shows the shared placeholder — the
|
|
4768
|
+
// "Add image" label on the canvas, the bare blank in Preview (IS_PREVIEW), which is what the
|
|
4769
|
+
// live site shows. An unmarked Image gets null and renders exactly as before.
|
|
4770
|
+
if (node.type === 'Image') {
|
|
4771
|
+
const src = node.traits?.find(t => t.name === 'src')?.default;
|
|
4772
|
+
const label = this.isPreview ? null : this.labels('builder.chrome.addImage', 'Add image');
|
|
4773
|
+
safeSetInput(componentRef, 'emptySrc', emptyImageSrc(node, src, label));
|
|
4774
|
+
}
|
|
4700
4775
|
// Build initial style map from styleTraits defaults.
|
|
4701
4776
|
const initialStyle = {};
|
|
4702
4777
|
if (node.styleTraits?.length) {
|
|
@@ -4714,7 +4789,10 @@ class RenderDirective {
|
|
|
4714
4789
|
// registry strips the props a type's renderer owns (a Dialog's positioning) on every rule.
|
|
4715
4790
|
if (cssId) {
|
|
4716
4791
|
this.styleRegistry.setNodeType(cssId, node.type);
|
|
4717
|
-
|
|
4792
|
+
// The default hover transition (shared, marker-aware — the engine emits the same one):
|
|
4793
|
+
// without it a hovering node's base rule, re-upserted here on every render, dropped the
|
|
4794
|
+
// transition page-ui had added on load, and the canvas snapped where the site eased.
|
|
4795
|
+
const composedBase = composeVirtualTraits(withDefaultHoverTransition(initialStyle, node.stateStyles, node.elementStyle));
|
|
4718
4796
|
this.styleRegistry.upsert(cssId, composedBase);
|
|
4719
4797
|
// Restore per-state overrides saved from a previous session.
|
|
4720
4798
|
// Every state set at base OR at any breakpoint — so a breakpoint-only state (a Mobile-only
|
|
@@ -4813,10 +4891,12 @@ class RenderDirective {
|
|
|
4813
4891
|
// For layout components the host element is <app-section>; for leaf components
|
|
4814
4892
|
// it is e.g. <app-card>. Either way this is the correct inspectable element.
|
|
4815
4893
|
const nativeEl = componentRef.location?.nativeElement ?? null;
|
|
4816
|
-
// The element-style marker (
|
|
4817
|
-
//
|
|
4818
|
-
//
|
|
4819
|
-
|
|
4894
|
+
// The design-system classes — the element-style marker (§3b-bis) and the section colour scheme
|
|
4895
|
+
// (§3c) — on the HOST, as both engine paths do, from the ONE shared helper. Component CSS that
|
|
4896
|
+
// carries the system look is scoped to the marker, so a node saved before DS2 keeps its exact
|
|
4897
|
+
// pre-DS2 look; the scheme class is where the token sheet re-declares the section's tokens.
|
|
4898
|
+
// Clones carry both (they render the same look).
|
|
4899
|
+
syncNodeDesignClasses(nativeEl, node);
|
|
4820
4900
|
// Custom element host defaults to display:inline. Set it to block so it participates
|
|
4821
4901
|
// properly in layout and CDK can capture its bounding rect. SKIP for directive-hosts: the
|
|
4822
4902
|
// host is a real element with its own display, and an inline style here out-ranks both
|
|
@@ -5557,53 +5637,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImpo
|
|
|
5557
5637
|
type: Output
|
|
5558
5638
|
}] } });
|
|
5559
5639
|
|
|
5560
|
-
/**
|
|
5561
|
-
* Canvas data preview used to come from host-provided content services (IOX_CONTENT_SERVICE /
|
|
5562
|
-
* IOX_SHOP_SERVICE), whose `getContent(contentType, orgId)` hit the ADMIN resources endpoint and
|
|
5563
|
-
* accepted no filters — so the Repeater/Slider ignored every data-source filter. Data now flows
|
|
5564
|
-
* through BuilderDataSourceService + the shared planDataSource, configured with
|
|
5565
|
-
* IOX_DATA_SOURCE_ENDPOINTS. Those tokens are gone; do not reintroduce a fetch that bypasses it.
|
|
5566
|
-
*/
|
|
5567
|
-
/** Optional font manager. Provide from the host app to populate the fontFamily dropdown. */
|
|
5568
|
-
const IOX_FONT_MANAGER = new InjectionToken('IOX_FONT_MANAGER');
|
|
5569
|
-
/**
|
|
5570
|
-
* Translates the builder library's OWN chrome.
|
|
5571
|
-
*
|
|
5572
|
-
* The library cannot depend on ngx-translate — that is the host app's choice — but its toolbar was
|
|
5573
|
-
* hardcoded English, which shows through as untranslated controls in a Hebrew/RTL admin. This token
|
|
5574
|
-
* lets the host route those strings through its own i18n while the library keeps working standalone:
|
|
5575
|
-
* unprovided, `defaultBuilderLabels` returns the English text, so nothing ever renders a raw key.
|
|
5576
|
-
*
|
|
5577
|
-
* Keys are namespaced `builder.chrome.*` and listed in `BUILDER_CHROME_EN` below — that object is
|
|
5578
|
-
* the contract. A host providing this token should add those keys to its own bundles.
|
|
5579
|
-
*/
|
|
5580
|
-
const IOX_BUILDER_LABELS = new InjectionToken('IOX_BUILDER_LABELS', {
|
|
5581
|
-
providedIn: 'root',
|
|
5582
|
-
factory: () => defaultBuilderLabels,
|
|
5583
|
-
});
|
|
5584
|
-
/** Standalone behaviour: the English text the library ships with. */
|
|
5585
|
-
const defaultBuilderLabels = (_key, fallback) => fallback;
|
|
5586
|
-
/**
|
|
5587
|
-
* Every user-visible string in the builder's own chrome, so a host can copy this into its bundles
|
|
5588
|
-
* in one go rather than discovering keys one missing label at a time.
|
|
5589
|
-
*/
|
|
5590
|
-
const BUILDER_CHROME_EN = Object.freeze({
|
|
5591
|
-
'builder.chrome.select': 'Select',
|
|
5592
|
-
'builder.chrome.pan': 'Pan',
|
|
5593
|
-
'builder.chrome.style': 'Style',
|
|
5594
|
-
'builder.chrome.publish': 'Publish',
|
|
5595
|
-
'builder.chrome.unpublish': 'Unpublish',
|
|
5596
|
-
'builder.chrome.breakpoint': 'Breakpoint',
|
|
5597
|
-
'builder.chrome.screenWidth': 'Screen width',
|
|
5598
|
-
'builder.chrome.zoom': 'Zoom',
|
|
5599
|
-
'builder.chrome.audit': 'Responsive audit',
|
|
5600
|
-
'builder.chrome.auditHint': 'Responsive audit — what is broken at this width',
|
|
5601
|
-
'builder.chrome.undo': 'Undo',
|
|
5602
|
-
'builder.chrome.redo': 'Redo',
|
|
5603
|
-
'builder.chrome.save': 'Save',
|
|
5604
|
-
'builder.chrome.preview': 'Preview',
|
|
5605
|
-
});
|
|
5606
|
-
|
|
5607
5640
|
class ToolbarComponent {
|
|
5608
5641
|
get isPublished() {
|
|
5609
5642
|
return this.pageStatus === 'published';
|
|
@@ -6532,7 +6565,7 @@ class BuilderComponent {
|
|
|
6532
6565
|
this.initLenis();
|
|
6533
6566
|
// Background / typography: until this existed the Page panel wrote a background
|
|
6534
6567
|
// that only appeared once the site was published.
|
|
6535
|
-
this.pageStyleCss = compilePageStyle(this.pageSettings?.style);
|
|
6568
|
+
this.pageStyleCss = compilePageStyle(this.pageSettings?.style, { designSystem: this.pageSettings?.designSystem === true });
|
|
6536
6569
|
}
|
|
6537
6570
|
if (changes['globalElements']) {
|
|
6538
6571
|
// The *ngIf on the global overlay renders after this hook — defer so
|
|
@@ -10627,6 +10660,7 @@ class BuilderContainerComponentConfig extends ComponentConfig {
|
|
|
10627
10660
|
this.children = [];
|
|
10628
10661
|
this.traits = [
|
|
10629
10662
|
new TraitConfig('htmlTag', 'HTML Tag', TraitInputType.Select, ['div', 'section', 'article', 'header', 'footer', 'main', 'nav', 'ul', 'ol', 'li'], 'div'),
|
|
10663
|
+
buildColorSchemeTrait(),
|
|
10630
10664
|
];
|
|
10631
10665
|
this.styleTraits = buildFullStyleTraits();
|
|
10632
10666
|
this.applyStyleDefaults({
|
|
@@ -11052,6 +11086,7 @@ class BuilderLinkedContainerConfig extends ComponentConfig {
|
|
|
11052
11086
|
{ label: 'Parent frame', value: '_parent' },
|
|
11053
11087
|
{ label: 'Full window', value: '_top' },
|
|
11054
11088
|
], '_self'),
|
|
11089
|
+
buildColorSchemeTrait(),
|
|
11055
11090
|
];
|
|
11056
11091
|
this.styleTraits = buildFullStyleTraits();
|
|
11057
11092
|
this.applyStyleDefaults({
|
|
@@ -11178,7 +11213,7 @@ class SectionComponentConfig extends ComponentConfig {
|
|
|
11178
11213
|
constructor() {
|
|
11179
11214
|
super('Section', 'app-section', 'ph-thin ph-rows', 'Layout');
|
|
11180
11215
|
this.children = [];
|
|
11181
|
-
this.traits = [];
|
|
11216
|
+
this.traits = [buildColorSchemeTrait()];
|
|
11182
11217
|
this.styleTraits = buildFullStyleTraits();
|
|
11183
11218
|
this.applyStyleDefaults({
|
|
11184
11219
|
width: 'auto',
|