@vectoriox/iox-ui 4.36.0 → 4.38.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.
@@ -5605,7 +5605,7 @@ const SEO_CHANGE_FREQ_OPTIONS = [
5605
5605
  * Empty branches are dropped rather than left as `{}`, so `if (seo.og)` is a meaningful test.
5606
5606
  */
5607
5607
  function normalizeSeoDoc(raw) {
5608
- const src = asRecord(raw);
5608
+ const src = asRecord$1(raw);
5609
5609
  if (!src)
5610
5610
  return {};
5611
5611
  const og = compact({
@@ -5640,7 +5640,7 @@ function normalizeSeoDoc(raw) {
5640
5640
  }
5641
5641
  /** Read `src[branch][leaf]` without assuming the branch exists or is an object. */
5642
5642
  function pick(src, branch, leaf) {
5643
- const nested = asRecord(src[branch]);
5643
+ const nested = asRecord$1(src[branch]);
5644
5644
  return nested ? nested[leaf] : undefined;
5645
5645
  }
5646
5646
  /**
@@ -5651,7 +5651,7 @@ function pick(src, branch, leaf) {
5651
5651
  * `undefined` here and `resolveSeo` fills it in from the lower rungs.
5652
5652
  */
5653
5653
  function seoString(value) {
5654
- const wrapper = asRecord(value);
5654
+ const wrapper = asRecord$1(value);
5655
5655
  const raw = wrapper ? wrapper['override'] : value;
5656
5656
  if (typeof raw === 'number')
5657
5657
  return String(raw);
@@ -5696,10 +5696,10 @@ function structured(value) {
5696
5696
  }
5697
5697
  if (Array.isArray(value))
5698
5698
  return value.length ? value : undefined;
5699
- const record = asRecord(value);
5699
+ const record = asRecord$1(value);
5700
5700
  return record && Object.keys(record).length ? record : undefined;
5701
5701
  }
5702
- function asRecord(value) {
5702
+ function asRecord$1(value) {
5703
5703
  return value !== null && typeof value === 'object' && !Array.isArray(value)
5704
5704
  ? value
5705
5705
  : undefined;
@@ -5933,14 +5933,14 @@ function resolveSeo(seo, ctx = {}) {
5933
5933
  let derived;
5934
5934
  const content = () => (derived ??= deriveSeoFromContent(ctx.tree, ctx.resolvedData));
5935
5935
  for (const field of SEO_BINDABLE_FIELDS) {
5936
- if (readField(out, field) !== undefined)
5936
+ if (readField$1(out, field) !== undefined)
5937
5937
  continue; // an override won
5938
- const stored = fieldValue(raw, field);
5938
+ const stored = fieldValue$1(raw, field);
5939
5939
  // Rung 2 — the binding.
5940
5940
  if (stored?.binding) {
5941
5941
  const value = resolveSeoBinding(stored.binding, ctx.resolvedData);
5942
5942
  if (value !== undefined) {
5943
- writeField(out, field, value);
5943
+ writeField$1(out, field, value);
5944
5944
  continue;
5945
5945
  }
5946
5946
  }
@@ -5950,7 +5950,7 @@ function resolveSeo(seo, ctx = {}) {
5950
5950
  const source = SEO_AUTO_SOURCES.find(entry => entry.field === field)?.source;
5951
5951
  const auto = source ? autoValue(source, content, ctx) : undefined;
5952
5952
  if (auto !== undefined)
5953
- writeField(out, field, auto);
5953
+ writeField$1(out, field, auto);
5954
5954
  }
5955
5955
  // One last pass so a resolved value gets the same trimming and empty-branch dropping as a stored
5956
5956
  // one — `if (seo.og)` must keep meaning something.
@@ -6067,20 +6067,20 @@ function truncate(value, max) {
6067
6067
  return (lastSpace > max * 0.6 ? cut.slice(0, lastSpace) : cut).trimEnd() + '…';
6068
6068
  }
6069
6069
  // ── dotted-path access over the document, so the field table stays data and not a switch ───────────
6070
- function fieldValue(raw, field) {
6071
- const value = readField(raw, field);
6070
+ function fieldValue$1(raw, field) {
6071
+ const value = readField$1(raw, field);
6072
6072
  if (value === null || typeof value !== 'object' || Array.isArray(value))
6073
6073
  return undefined;
6074
6074
  return value;
6075
6075
  }
6076
- function readField(doc, field) {
6076
+ function readField$1(doc, field) {
6077
6077
  const [branch, leaf] = field.split('.');
6078
6078
  if (!leaf)
6079
6079
  return doc[branch];
6080
6080
  const nested = doc[branch];
6081
6081
  return nested && typeof nested === 'object' ? nested[leaf] : undefined;
6082
6082
  }
6083
- function writeField(doc, field, value) {
6083
+ function writeField$1(doc, field, value) {
6084
6084
  const [branch, leaf] = field.split('.');
6085
6085
  if (!leaf) {
6086
6086
  doc[branch] = value;
@@ -6091,6 +6091,154 @@ function writeField(doc, field, value) {
6091
6091
  doc[branch] = nested;
6092
6092
  }
6093
6093
 
6094
+ const MAX_LENGTHS = {
6095
+ title: SEO_TITLE_MAX,
6096
+ description: SEO_DESCRIPTION_MAX,
6097
+ 'og.description': SEO_DESCRIPTION_MAX,
6098
+ 'twitter.description': SEO_DESCRIPTION_MAX,
6099
+ };
6100
+ /**
6101
+ * Describe every bindable field for the authoring panel.
6102
+ *
6103
+ * ⚠️ `resolved` is deliberately EMPTY for a bound field on the builder side. The canvas has no
6104
+ * page-level resolved data — each component fetches its own — so a bound value genuinely is not
6105
+ * knowable here. Showing the binding expression and saying so is honest; inventing a preview from
6106
+ * design-time props is how a placeholder ends up looking like real content.
6107
+ */
6108
+ function describeSeoFields(seo, ctx = {}) {
6109
+ const raw = asRecord(seo) ?? {};
6110
+ const resolvedDoc = resolveSeo(seo, ctx);
6111
+ return SEO_BINDABLE_FIELDS.map(field => {
6112
+ const stored = fieldValue(raw, field);
6113
+ const override = seoString(readField(raw, field)) ?? '';
6114
+ const binding = stored?.binding;
6115
+ const resolved = seoString(readField(resolvedDoc, field)) ?? '';
6116
+ let source;
6117
+ if (override)
6118
+ source = 'manual';
6119
+ else if (binding)
6120
+ source = 'bound';
6121
+ else if (resolved)
6122
+ source = 'auto';
6123
+ else
6124
+ source = 'empty';
6125
+ return {
6126
+ field,
6127
+ override,
6128
+ binding,
6129
+ // A bound field's value comes from data this side cannot see.
6130
+ resolved: source === 'bound' ? '' : resolved,
6131
+ source,
6132
+ maxLength: MAX_LENGTHS[field],
6133
+ };
6134
+ });
6135
+ }
6136
+ /** Set a field's typed value. An empty string CLEARS the override so the lower rungs take over. */
6137
+ function setSeoOverride(seo, field, value) {
6138
+ const next = clone(seo);
6139
+ const text = value?.trim() ?? '';
6140
+ const existing = fieldValue(next, field);
6141
+ if (!text) {
6142
+ // Nothing else on the field → drop it entirely, so the document stays free of `{}` husks.
6143
+ if (!existing?.binding && existing?.auto !== false)
6144
+ writeField(next, field, undefined);
6145
+ else
6146
+ writeField(next, field, stripUndefined({ binding: existing?.binding, auto: existing?.auto }));
6147
+ return next;
6148
+ }
6149
+ writeField(next, field, stripUndefined({ override: text, binding: existing?.binding, auto: existing?.auto }));
6150
+ return next;
6151
+ }
6152
+ /** Attach or replace a field's binding. `undefined` removes it. */
6153
+ function setSeoBinding(seo, field, binding) {
6154
+ const next = clone(seo);
6155
+ const existing = fieldValue(next, field);
6156
+ const value = stripUndefined({ override: existing?.override, binding, auto: existing?.auto });
6157
+ writeField(next, field, Object.keys(value).length ? value : undefined);
6158
+ return next;
6159
+ }
6160
+ /** Turn the automatic rung on or off for a field. Off leaves the field genuinely empty. */
6161
+ function setSeoAuto(seo, field, enabled) {
6162
+ const next = clone(seo);
6163
+ const existing = fieldValue(next, field);
6164
+ const value = stripUndefined({
6165
+ override: existing?.override,
6166
+ binding: existing?.binding,
6167
+ auto: enabled ? undefined : false,
6168
+ });
6169
+ writeField(next, field, Object.keys(value).length ? value : undefined);
6170
+ return next;
6171
+ }
6172
+ /**
6173
+ * Set a field that is NOT part of the ladder — `robots`, `twitter.card`, `structuredData`,
6174
+ * `sitemap.*`. These are pick-lists, switches and blobs: they have no override/binding/auto, so they
6175
+ * are stored as plain values, exactly as the normalizer reads them.
6176
+ *
6177
+ * `undefined`, `null` and `''` remove the field, so an unset pick-list leaves no husk behind.
6178
+ */
6179
+ function setSeoValue(seo, field, value) {
6180
+ const next = clone(seo);
6181
+ const empty = value === undefined || value === null || (typeof value === 'string' && !value.trim());
6182
+ writeField(next, field, empty ? undefined : value);
6183
+ return next;
6184
+ }
6185
+ /** Read any field's plain stored value — the counterpart of `setSeoValue`. */
6186
+ function getSeoValue(seo, field) {
6187
+ return readField(asRecord(seo) ?? {}, field);
6188
+ }
6189
+ /** Drop everything an author set on a field — back to the automatic rung. */
6190
+ function resetSeoField(seo, field) {
6191
+ const next = clone(seo);
6192
+ writeField(next, field, undefined);
6193
+ return next;
6194
+ }
6195
+ // ── shared dotted-path plumbing ───────────────────────────────────────────────────────────────
6196
+ function clone(seo) {
6197
+ return JSON.parse(JSON.stringify(asRecord(seo) ?? {}));
6198
+ }
6199
+ function asRecord(value) {
6200
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
6201
+ ? value
6202
+ : undefined;
6203
+ }
6204
+ function stripUndefined(value) {
6205
+ const out = {};
6206
+ for (const [key, entry] of Object.entries(value))
6207
+ if (entry !== undefined)
6208
+ out[key] = entry;
6209
+ return out;
6210
+ }
6211
+ function fieldValue(doc, field) {
6212
+ const value = readField(doc, field);
6213
+ return asRecord(value);
6214
+ }
6215
+ function readField(doc, field) {
6216
+ const [branch, leaf] = field.split('.');
6217
+ if (!leaf)
6218
+ return doc[branch];
6219
+ const nested = asRecord(doc[branch]);
6220
+ return nested ? nested[leaf] : undefined;
6221
+ }
6222
+ function writeField(doc, field, value) {
6223
+ const [branch, leaf] = field.split('.');
6224
+ if (!leaf) {
6225
+ if (value === undefined)
6226
+ delete doc[branch];
6227
+ else
6228
+ doc[branch] = value;
6229
+ return;
6230
+ }
6231
+ const nested = (asRecord(doc[branch]) ?? {});
6232
+ if (value === undefined)
6233
+ delete nested[leaf];
6234
+ else
6235
+ nested[leaf] = value;
6236
+ if (Object.keys(nested).length)
6237
+ doc[branch] = nested;
6238
+ else
6239
+ delete doc[branch];
6240
+ }
6241
+
6094
6242
  /**
6095
6243
  * Element context state — shared types.
6096
6244
  *
@@ -6778,5 +6926,5 @@ function effectiveTransitionId(anim) {
6778
6926
  * Generated bundle index. Do not edit.
6779
6927
  */
6780
6928
 
6781
- export { AOSService, AnalyticsService, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, ENVIRONMENT, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, defaultMessageResolver, deriveSeoFromContent, effectiveTransitionId, excludeSelf, feelFor, getByPath, initialSlotValues, isActionEnabled, isContextAction, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, normalizeIconClass, parentBreakpoint, parseUrlList, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resolveBoundValue, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSeo, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, stateNamesIn, stripSuppressedProps, styleKeyToKebab, variableAliases, variableItemsFrom, withContextSlots, wrapInBreakpointQuery, wrapInMediaQuery };
6929
+ export { AOSService, AnalyticsService, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, ENVIRONMENT, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, defaultMessageResolver, deriveSeoFromContent, describeSeoFields, effectiveTransitionId, excludeSelf, feelFor, getByPath, getSeoValue, initialSlotValues, isActionEnabled, isContextAction, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, normalizeIconClass, parentBreakpoint, parseUrlList, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resetSeoField, resolveBoundValue, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSeo, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, setSeoAuto, setSeoBinding, setSeoOverride, setSeoValue, stateNamesIn, stripSuppressedProps, styleKeyToKebab, variableAliases, variableItemsFrom, withContextSlots, wrapInBreakpointQuery, wrapInMediaQuery };
6782
6930
  //# sourceMappingURL=vectoriox-iox-ui.mjs.map