@vectoriox/iox-ui 4.14.1 → 4.15.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.
|
@@ -2653,6 +2653,106 @@ function resolveRelativeInto(dataSources, resolved, routeParams = {}) {
|
|
|
2653
2653
|
return resolved;
|
|
2654
2654
|
}
|
|
2655
2655
|
|
|
2656
|
+
/**
|
|
2657
|
+
* Binding pipes — render-time value transforms (UI label: "Filters").
|
|
2658
|
+
*
|
|
2659
|
+
* A binding resolves a raw value (`resolvePath(sourceData, path)`); a pipe chain then reshapes it for
|
|
2660
|
+
* display (format a timestamp, upper-case, truncate, …). This is the SINGLE shared implementation used
|
|
2661
|
+
* by BOTH the builder canvas and the SSR engine — the engine renders layout JSON to a STRING and can't
|
|
2662
|
+
* use Angular pipes, and `resolvePath` is already duplicated across the apply points, so the transform
|
|
2663
|
+
* MUST be one pure, transport-agnostic function applied identically everywhere. Never fork it.
|
|
2664
|
+
*
|
|
2665
|
+
* See iox-ai-guidance/architecture/builder/binding-filters-plan.md.
|
|
2666
|
+
*/
|
|
2667
|
+
// ── Date / time (Intl locale presets — locale-aware, zero-dep, browser + Node identical) ──────────
|
|
2668
|
+
const DATE_PRESETS = {
|
|
2669
|
+
short: { dateStyle: 'short' },
|
|
2670
|
+
medium: { dateStyle: 'medium' },
|
|
2671
|
+
long: { dateStyle: 'long' },
|
|
2672
|
+
full: { dateStyle: 'full' },
|
|
2673
|
+
};
|
|
2674
|
+
const DATETIME_PRESETS = {
|
|
2675
|
+
short: { dateStyle: 'short', timeStyle: 'short' },
|
|
2676
|
+
medium: { dateStyle: 'medium', timeStyle: 'short' },
|
|
2677
|
+
long: { dateStyle: 'long', timeStyle: 'medium' },
|
|
2678
|
+
full: { dateStyle: 'full', timeStyle: 'long' },
|
|
2679
|
+
};
|
|
2680
|
+
/** Coerce an ISO string / epoch number / Date to a valid Date, or null (→ pipes pass the value through). */
|
|
2681
|
+
function toDate(value) {
|
|
2682
|
+
if (value instanceof Date)
|
|
2683
|
+
return isNaN(value.getTime()) ? null : value;
|
|
2684
|
+
if (typeof value === 'number') {
|
|
2685
|
+
const d = new Date(value);
|
|
2686
|
+
return isNaN(d.getTime()) ? null : d;
|
|
2687
|
+
}
|
|
2688
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
2689
|
+
const d = new Date(value);
|
|
2690
|
+
return isNaN(d.getTime()) ? null : d;
|
|
2691
|
+
}
|
|
2692
|
+
return null;
|
|
2693
|
+
}
|
|
2694
|
+
function formatDate(value, args, ctx, presets) {
|
|
2695
|
+
const d = toDate(value);
|
|
2696
|
+
if (!d)
|
|
2697
|
+
return value; // never throw — unparseable input passes through unchanged
|
|
2698
|
+
const preset = args[0] || 'medium';
|
|
2699
|
+
return new Intl.DateTimeFormat(ctx.locale, presets[preset] ?? presets['medium']).format(d);
|
|
2700
|
+
}
|
|
2701
|
+
/** The registry — adding a pipe here (+ a descriptor below) makes it work on both sides and appear in
|
|
2702
|
+
* the authoring UI. Keyed by name; unknown names are passed through by `applyBindingPipes`. */
|
|
2703
|
+
const PIPE_REGISTRY = {
|
|
2704
|
+
date: (v, args, ctx) => formatDate(v, args, ctx, DATE_PRESETS),
|
|
2705
|
+
datetime: (v, args, ctx) => formatDate(v, args, ctx, DATETIME_PRESETS),
|
|
2706
|
+
uppercase: (v) => (v == null ? v : String(v).toUpperCase()),
|
|
2707
|
+
lowercase: (v) => (v == null ? v : String(v).toLowerCase()),
|
|
2708
|
+
truncate: (v, args) => {
|
|
2709
|
+
if (v == null)
|
|
2710
|
+
return v;
|
|
2711
|
+
const s = String(v);
|
|
2712
|
+
const len = Number(args[0]) || 100;
|
|
2713
|
+
const suffix = args[1] != null ? String(args[1]) : '…';
|
|
2714
|
+
return s.length > len ? s.slice(0, len) + suffix : s;
|
|
2715
|
+
},
|
|
2716
|
+
number: (v, args, ctx) => {
|
|
2717
|
+
const n = typeof v === 'number' ? v : parseFloat(v);
|
|
2718
|
+
if (!Number.isFinite(n))
|
|
2719
|
+
return v;
|
|
2720
|
+
const opts = {};
|
|
2721
|
+
if (args[0] != null && args[0] !== '') {
|
|
2722
|
+
opts.minimumFractionDigits = Number(args[0]);
|
|
2723
|
+
opts.maximumFractionDigits = Number(args[0]);
|
|
2724
|
+
}
|
|
2725
|
+
return new Intl.NumberFormat(ctx.locale, opts).format(n);
|
|
2726
|
+
},
|
|
2727
|
+
};
|
|
2728
|
+
/**
|
|
2729
|
+
* Apply a binding's pipe chain to a resolved value, LEFT→RIGHT. Pure. An empty/undefined chain returns
|
|
2730
|
+
* the value untouched; an unknown pipe name is skipped (forward-compatible with newer authored pipes).
|
|
2731
|
+
* Call this at every binding-resolution point (builder canvas + engine SSR + engine hydration).
|
|
2732
|
+
*/
|
|
2733
|
+
function applyBindingPipes(value, pipes, ctx = {}) {
|
|
2734
|
+
if (!pipes?.length)
|
|
2735
|
+
return value;
|
|
2736
|
+
return pipes.reduce((v, p) => {
|
|
2737
|
+
const fn = p && PIPE_REGISTRY[p.name];
|
|
2738
|
+
return fn ? fn(v, p.args ?? [], ctx) : v;
|
|
2739
|
+
}, value);
|
|
2740
|
+
}
|
|
2741
|
+
const PRESET_OPTIONS = [
|
|
2742
|
+
{ label: 'Short', value: 'short' },
|
|
2743
|
+
{ label: 'Medium', value: 'medium' },
|
|
2744
|
+
{ label: 'Long', value: 'long' },
|
|
2745
|
+
{ label: 'Full', value: 'full' },
|
|
2746
|
+
];
|
|
2747
|
+
const PIPE_DESCRIPTORS = [
|
|
2748
|
+
{ name: 'date', label: 'Date', args: [{ key: 'preset', label: 'Format', control: 'select', options: PRESET_OPTIONS, default: 'medium' }] },
|
|
2749
|
+
{ name: 'datetime', label: 'Date & time', args: [{ key: 'preset', label: 'Format', control: 'select', options: PRESET_OPTIONS, default: 'medium' }] },
|
|
2750
|
+
{ name: 'uppercase', label: 'UPPERCASE', args: [] },
|
|
2751
|
+
{ name: 'lowercase', label: 'lowercase', args: [] },
|
|
2752
|
+
{ name: 'truncate', label: 'Truncate', args: [{ key: 'length', label: 'Max length', control: 'number', default: 100 }] },
|
|
2753
|
+
{ name: 'number', label: 'Number', args: [{ key: 'decimals', label: 'Decimals', control: 'number', default: null }] },
|
|
2754
|
+
];
|
|
2755
|
+
|
|
2656
2756
|
/**
|
|
2657
2757
|
* Cinematic page-transition presets — the SINGLE SOURCE OF TRUTH shared by the page builder
|
|
2658
2758
|
* (preview) and the SSR client engine (production). Pure, transport-agnostic: this module only
|
|
@@ -3087,5 +3187,5 @@ function effectiveTransitionId(anim) {
|
|
|
3087
3187
|
* Generated bundle index. Do not edit.
|
|
3088
3188
|
*/
|
|
3089
3189
|
|
|
3090
|
-
export { AOSService, AnalyticsService, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CardComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_WIDTH_BY_TYPE, ENVIRONMENT, IOX_BUILDER_EVENTS, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxPageComponent, IoxPageModule, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, applyFeel, buildDataSourceFilter, buildRelatedFilter, buildTransitionTimeline, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, dataSourcePlanToRequest, effectiveTransitionId, excludeSelf, feelFor, getByPath, isReservedAlias, legacyEnterToTransition, matchRouteParams, normalizeCollectionResult, planDataSource, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resolveDerivedInto, resolvePageTransition, resolveRelativeInto, resolveRepeaterItems, resolveSiblings, resolveSingleItemId, rewriteViewportUnits, stripSuppressedProps, styleKeyToKebab };
|
|
3190
|
+
export { AOSService, AnalyticsService, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CardComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_WIDTH_BY_TYPE, ENVIRONMENT, IOX_BUILDER_EVENTS, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxPageComponent, IoxPageModule, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, applyBindingPipes, applyFeel, buildDataSourceFilter, buildRelatedFilter, buildTransitionTimeline, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, dataSourcePlanToRequest, effectiveTransitionId, excludeSelf, feelFor, getByPath, isReservedAlias, legacyEnterToTransition, matchRouteParams, normalizeCollectionResult, planDataSource, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resolveDerivedInto, resolvePageTransition, resolveRelativeInto, resolveRepeaterItems, resolveSiblings, resolveSingleItemId, rewriteViewportUnits, stripSuppressedProps, styleKeyToKebab };
|
|
3091
3191
|
//# sourceMappingURL=vectoriox-iox-ui.mjs.map
|