@aiconomy/aico-components 0.1.0 → 0.2.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.
Files changed (30) hide show
  1. package/dist/aico-components/aico-components.esm.js +1 -1
  2. package/dist/aico-components/aico-components.esm.js.map +1 -1
  3. package/dist/aico-components/{p-17b7115a.entry.js → p-cf9b69ea.entry.js} +3 -3
  4. package/dist/aico-components/p-cf9b69ea.entry.js.map +1 -0
  5. package/dist/cjs/aico-album-content_28.cjs.entry.js +131 -10
  6. package/dist/cjs/aico-album-content_28.cjs.entry.js.map +1 -1
  7. package/dist/cjs/aico-components.cjs.js +1 -1
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/collection/components/aico-article-detail/aico-article-detail.js +11 -7
  10. package/dist/collection/components/aico-article-detail/aico-article-detail.js.map +1 -1
  11. package/dist/collection/components/aico-neo-content/aico-neo-content.js +53 -2
  12. package/dist/collection/components/aico-neo-content/aico-neo-content.js.map +1 -1
  13. package/dist/collection/utils/neo/neo-lead-trim.js +106 -0
  14. package/dist/collection/utils/neo/neo-lead-trim.js.map +1 -0
  15. package/dist/components/aico-article-detail2.js +11 -7
  16. package/dist/components/aico-article-detail2.js.map +1 -1
  17. package/dist/components/aico-neo-content2.js +126 -5
  18. package/dist/components/aico-neo-content2.js.map +1 -1
  19. package/dist/esm/aico-album-content_28.entry.js +131 -10
  20. package/dist/esm/aico-album-content_28.entry.js.map +1 -1
  21. package/dist/esm/aico-components.js +1 -1
  22. package/dist/esm/loader.js +1 -1
  23. package/dist/ssr/index.js +134 -11
  24. package/dist/ssr/index.mjs +134 -11
  25. package/dist/types/components/aico-article-detail/aico-article-detail.d.ts +3 -1
  26. package/dist/types/components/aico-neo-content/aico-neo-content.d.ts +10 -0
  27. package/dist/types/components.d.ts +16 -0
  28. package/dist/types/utils/neo/neo-lead-trim.d.ts +33 -0
  29. package/package.json +1 -1
  30. package/dist/aico-components/p-17b7115a.entry.js.map +0 -1
@@ -13957,11 +13957,11 @@ const AicoArticleDetail = class {
13957
13957
  const translation = (_a = this.article.attributes.translations.find(translation => translation.locale === this.locale)) !== null && _a !== void 0 ? _a : null;
13958
13958
  const category = (_c = (_b = this.article.attributes.newsCategory) === null || _b === void 0 ? void 0 : _b.translations.find(translation => translation.locale === this.locale)) !== null && _c !== void 0 ? _c : null;
13959
13959
  const articleDate = new Date(this.article.attributes.publishDate);
13960
- const content = this.mapBodyContent();
13960
+ const content = this.mapBodyContent(translation);
13961
13961
  const headlineFocusX = this.article.attributes.headlineImageFocusXPercentage ? `${this.article.attributes.headlineImageFocusXPercentage}%` : 'center';
13962
13962
  const headlineFocusY = this.article.attributes.headlineImageFocusYPercentage ? `${this.article.attributes.headlineImageFocusYPercentage}%` : 'center';
13963
13963
  const headlineImage = (_d = translation === null || translation === void 0 ? void 0 : translation.headlineImage) !== null && _d !== void 0 ? _d : this.article.attributes.headlineImage;
13964
- return (h(Host, { key: 'f5b0a0d80a16cc93bf0158ce61e41e9d46af0d7d' }, h("figure", { key: '31a5a62a3cef0947b37eddeaad0e235719932888', class: "figure" }, h("blockquote", { key: '7f62b7e19ac4ad766973f91f4bac6dafe7c5eee8', class: "blockquote" }, h("h2", { key: '01bd07a082a7fd5961dfd03503c99d614b460f14', class: "text-uppercase" }, (_e = translation === null || translation === void 0 ? void 0 : translation.name) !== null && _e !== void 0 ? _e : this.article.attributes.name)), headlineImage && h("img", { key: '874ca0c3a11013f9966229af600f0f22ad41a008', class: "figure-img img-fluid rounded object-fit-cover", style: { 'object-position': `${headlineFocusX} ${headlineFocusY}` }, alt: "Headline image", src: headlineImage }), h(ConditionalRender, { key: '24191f3d2f5b41b3bc1477ad2f58d22a421f5dc7', condition: !this.hideDateAndAuthor }, h("figcaption", { key: '54f67a7575a164186924a5af9ec17815ba1fb819', class: "figure-caption mb-1" }, articleDate.toLocaleDateString('en-US', this.dateOptions), " by ", h("cite", { key: '5f58c6810a3ebf87d952bc5215df059bbafa8760', title: "Author" }, this.article.attributes.author))), h(ConditionalRender, { key: '120702974198d12f5948e65ff8f19ebcf1bf3d27', condition: !this.hideCategoryAndTags && !strIsNullOrEmptyOrWhitespace(category === null || category === void 0 ? void 0 : category.webName) }, h("span", { key: '21ef58fd94b6b11142536a7b7401e88013cdd6b5', class: "badge bg-info text-dark" }, category === null || category === void 0 ? void 0 : category.webName))), h("div", { key: '504fc30e0abc5617ea7b12d90770f2013a1a3d4a', class: "content-wrapper" }, content), h(ConditionalRender, { key: '895c5ee4b8e3c22e8264ed98ac9410f74cac0843', condition: !this.hideCategoryAndTags }, this.article.attributes.newsTags.map(tag => {
13964
+ return (h(Host, { key: '4973f50c2a561ff5f68ff16b29285dde0ef75f87' }, h("figure", { key: '363fdcf4f12d61022d5153216ad574f590dc3e82', class: "figure" }, h("blockquote", { key: '357d1a947423d3bb99748ebfe65c0ce6f95647cb', class: "blockquote" }, h("h2", { key: 'd1037e2b0b71bab77fc37b36f7533d6d141ac406', class: "text-uppercase" }, (_e = translation === null || translation === void 0 ? void 0 : translation.name) !== null && _e !== void 0 ? _e : this.article.attributes.name)), headlineImage && h("img", { key: '265565ff90b7b243555fb1c2aa5441e20826b43a', class: "figure-img img-fluid rounded object-fit-cover", style: { 'object-position': `${headlineFocusX} ${headlineFocusY}` }, alt: "Headline image", src: headlineImage }), h(ConditionalRender, { key: '3f94832f01549a5511a4927c53286c114953228d', condition: !this.hideDateAndAuthor }, h("figcaption", { key: '7afe217a895b0f9546a2beda40c9f143acdcc358', class: "figure-caption mb-1" }, articleDate.toLocaleDateString('en-US', this.dateOptions), " by ", h("cite", { key: '7a0c93292b1ed0bc39e8e94f68de9ba18ac99a36', title: "Author" }, this.article.attributes.author))), h(ConditionalRender, { key: 'a89fb90d8e7f6ba6048b43a119d127c7a6c6879b', condition: !this.hideCategoryAndTags && !strIsNullOrEmptyOrWhitespace(category === null || category === void 0 ? void 0 : category.webName) }, h("span", { key: '87aa1fe763f281238ed12d2b1dddbe043f58c8e6', class: "badge bg-info text-dark" }, category === null || category === void 0 ? void 0 : category.webName))), h("div", { key: 'e0bb9d8ebbedc684e4cb848042998874e3c7520b', class: "content-wrapper" }, content), h(ConditionalRender, { key: '81c6c20f4f8274a01ff8b65f1bf2c319e1811998', condition: !this.hideCategoryAndTags }, this.article.attributes.newsTags.map(tag => {
13965
13965
  var _a;
13966
13966
  const translation = (_a = tag.translations.find(translation => translation.locale === this.locale)) !== null && _a !== void 0 ? _a : null;
13967
13967
  return (h(ConditionalRender, { condition: !strIsNullOrEmptyOrWhitespace(translation === null || translation === void 0 ? void 0 : translation.webName) }, h("span", { class: "badge bg-light text-dark" }, translation.webName)));
@@ -13973,15 +13973,19 @@ const AicoArticleDetail = class {
13973
13973
  * then empty, null, or a stale copy) — when the Neo document has sections it
13974
13974
  * wins, mirroring the b2b storefront's precedence. Otherwise the legacy
13975
13975
  * rows render; a null/absent legacy builder renders an empty body instead
13976
- * of throwing.
13976
+ * of throwing. When this page already shows its own headline image/title
13977
+ * above the body, the Neo renderer is asked to trim a duplicate leading
13978
+ * hero image/heading from the document (see neo-lead-trim.ts).
13977
13979
  */
13978
- mapBodyContent() {
13979
- var _a, _b;
13980
+ mapBodyContent(translation) {
13981
+ var _a, _b, _c, _d;
13980
13982
  const neoDocument = this.article.attributes.contentBuilderNeoJson;
13981
13983
  if (neoDocumentHasContent(neoDocument)) {
13982
- return h("aico-neo-content", { neoDocument: neoDocument, locale: this.locale });
13984
+ const headlineImage = (_a = translation === null || translation === void 0 ? void 0 : translation.headlineImage) !== null && _a !== void 0 ? _a : this.article.attributes.headlineImage;
13985
+ const title = (_b = translation === null || translation === void 0 ? void 0 : translation.name) !== null && _b !== void 0 ? _b : this.article.attributes.name;
13986
+ return h("aico-neo-content", { neoDocument: neoDocument, locale: this.locale, trimLeadImage: !!headlineImage, dedupeTitle: title });
13983
13987
  }
13984
- const rows = (_b = (_a = this.article.attributes.contentBuilder) === null || _a === void 0 ? void 0 : _a.rows) !== null && _b !== void 0 ? _b : [];
13988
+ const rows = (_d = (_c = this.article.attributes.contentBuilder) === null || _c === void 0 ? void 0 : _c.rows) !== null && _d !== void 0 ? _d : [];
13985
13989
  return [...rows].sort((a, b) => a.order - b.order).map((row, index) => this.mapRowContent(row, index));
13986
13990
  }
13987
13991
  mapRowContent(row, index) {
@@ -20841,6 +20845,112 @@ function resolveLocale(document, locale, defaultLocale = null) {
20841
20845
  return resolved;
20842
20846
  }
20843
20847
 
20848
+ const ENTITIES = {
20849
+ '&': '&',
20850
+ '&lt;': '<',
20851
+ '&gt;': '>',
20852
+ '&quot;': '"',
20853
+ '&#39;': "'",
20854
+ '&nbsp;': ' ',
20855
+ };
20856
+ /** Plain text of an HTML fragment, whitespace-collapsed and lowercased (mirrors NeoNewsContentRenderer::normalizeText). */
20857
+ function normalizeText(html) {
20858
+ const stripped = html.replace(/<[^>]*>/g, '');
20859
+ const decoded = stripped.replace(/&amp;|&lt;|&gt;|&quot;|&#39;|&nbsp;/g, entity => ENTITIES[entity]);
20860
+ return decoded.replace(/\s+/g, ' ').trim().toLowerCase();
20861
+ }
20862
+ function headingText(element) {
20863
+ var _a;
20864
+ const text = (_a = element.content) === null || _a === void 0 ? void 0 : _a.text;
20865
+ return typeof text === 'string' ? text : '';
20866
+ }
20867
+ /** Filters one elements array, recursing into `columns` children. Returns the input array by reference when nothing changed. */
20868
+ function trimElements(elements, state) {
20869
+ const result = [];
20870
+ let changed = false;
20871
+ for (const element of elements) {
20872
+ if (element.type === 'columns') {
20873
+ const children = Array.isArray(element.children) ? element.children : [];
20874
+ const newChildren = trimElements(children, state);
20875
+ if (newChildren.length === 0) {
20876
+ changed = true;
20877
+ continue;
20878
+ }
20879
+ if (newChildren !== children) {
20880
+ changed = true;
20881
+ result.push(Object.assign(Object.assign({}, element), { children: newChildren }));
20882
+ }
20883
+ else {
20884
+ result.push(element);
20885
+ }
20886
+ continue;
20887
+ }
20888
+ if (element.type === 'image') {
20889
+ // Images never end the lead: kept or dropped, either way the next
20890
+ // element is still evaluated as leading.
20891
+ if (state.atLeadingEdge && state.dropLeadingImage) {
20892
+ changed = true;
20893
+ continue;
20894
+ }
20895
+ result.push(element);
20896
+ continue;
20897
+ }
20898
+ if (element.type === 'divider') {
20899
+ // Dividers don't end the lead either.
20900
+ result.push(element);
20901
+ continue;
20902
+ }
20903
+ if (element.type === 'heading') {
20904
+ if (state.atLeadingEdge && state.normalizedTitle !== null && normalizeText(headingText(element)) === state.normalizedTitle) {
20905
+ changed = true;
20906
+ continue;
20907
+ }
20908
+ result.push(element);
20909
+ state.atLeadingEdge = false;
20910
+ continue;
20911
+ }
20912
+ // Any other element type (text, html, button, video, gallery, slideshow, …) is kept and ends the lead.
20913
+ result.push(element);
20914
+ state.atLeadingEdge = false;
20915
+ }
20916
+ return changed ? result : elements;
20917
+ }
20918
+ /**
20919
+ * Preprocesses a locale-resolved Neo document, dropping lead content that
20920
+ * duplicates the host page's own header. Non-mutating: returns the input
20921
+ * unchanged (same reference) when there is nothing to do, otherwise a new
20922
+ * document with a new `sections` array (untouched sections/elements may be
20923
+ * reused by reference).
20924
+ */
20925
+ function trimNeoLead(document, options) {
20926
+ const sections = Array.isArray(document.sections) ? document.sections : [];
20927
+ if (sections.length === 0) {
20928
+ return document;
20929
+ }
20930
+ const dedupeTitle = options.dedupeTitle;
20931
+ const hasDedupeTitle = typeof dedupeTitle === 'string' && dedupeTitle.trim() !== '';
20932
+ if (!options.trimLeadImage && !hasDedupeTitle) {
20933
+ return document;
20934
+ }
20935
+ const state = {
20936
+ atLeadingEdge: true,
20937
+ dropLeadingImage: options.trimLeadImage,
20938
+ normalizedTitle: hasDedupeTitle ? normalizeText(dedupeTitle) : null,
20939
+ };
20940
+ const newSections = [];
20941
+ for (const section of sections) {
20942
+ const elements = Array.isArray(section.elements) ? section.elements : [];
20943
+ const newElements = trimElements(elements, state);
20944
+ if (newElements.length === 0) {
20945
+ // An empty section must not survive — this is what removes a
20946
+ // background-only hero section once its sole image is trimmed.
20947
+ continue;
20948
+ }
20949
+ newSections.push(newElements === elements ? section : Object.assign(Object.assign({}, section), { elements: newElements }));
20950
+ }
20951
+ return Object.assign(Object.assign({}, document), { sections: newSections });
20952
+ }
20953
+
20844
20954
  /**
20845
20955
  * news-neo-renderer.ts
20846
20956
  *
@@ -21979,12 +22089,14 @@ const AicoNeoContent = class {
21979
22089
  this.neoDocument = undefined;
21980
22090
  this.locale = 'de';
21981
22091
  this.defaultLocale = undefined;
22092
+ this.trimLeadImage = false;
22093
+ this.dedupeTitle = undefined;
21982
22094
  }
21983
22095
  componentWillLoad() {
21984
22096
  this.prepareHtml();
21985
22097
  }
21986
22098
  prepareHtml() {
21987
- var _a;
22099
+ var _a, _b;
21988
22100
  if (!neoDocumentHasContent(this.neoDocument)) {
21989
22101
  this.renderedHtml = '';
21990
22102
  return;
@@ -21993,6 +22105,13 @@ const AicoNeoContent = class {
21993
22105
  if (hasLocaleStructure(resolvedDocument)) {
21994
22106
  resolvedDocument = resolveLocale(resolvedDocument, this.locale, (_a = this.defaultLocale) !== null && _a !== void 0 ? _a : null);
21995
22107
  }
22108
+ if (this.trimLeadImage || this.dedupeTitle) {
22109
+ resolvedDocument = trimNeoLead(resolvedDocument, { trimLeadImage: this.trimLeadImage, dedupeTitle: (_b = this.dedupeTitle) !== null && _b !== void 0 ? _b : null });
22110
+ if (resolvedDocument.sections.length === 0) {
22111
+ this.renderedHtml = '';
22112
+ return;
22113
+ }
22114
+ }
21996
22115
  setActiveLocale(this.locale);
21997
22116
  this.renderedHtml = NewsNeo.render({ contentBuilderNeoJson: resolvedDocument });
21998
22117
  }
@@ -22004,13 +22123,15 @@ const AicoNeoContent = class {
22004
22123
  }
22005
22124
  }
22006
22125
  render() {
22007
- return (h(Host, { key: '82b5bdbc016d175f57ff0c2d9569da68728c304d' }, h("div", { key: '8a46741a6ce19c9e374928d6a4a0e4d76699f173', class: "aico-neo-content-mount", innerHTML: this.renderedHtml })));
22126
+ return (h(Host, { key: '663be625008bd9444656dfedd24cfe9fa97e7d43' }, h("div", { key: 'f0827191bf2ccc6d8cb35644103aa558d338382f', class: "aico-neo-content-mount", innerHTML: this.renderedHtml })));
22008
22127
  }
22009
22128
  get host() { return getElement$1(this); }
22010
22129
  static get watchers() { return {
22011
22130
  "neoDocument": ["prepareHtml"],
22012
22131
  "locale": ["prepareHtml"],
22013
- "defaultLocale": ["prepareHtml"]
22132
+ "defaultLocale": ["prepareHtml"],
22133
+ "trimLeadImage": ["prepareHtml"],
22134
+ "dedupeTitle": ["prepareHtml"]
22014
22135
  }; }
22015
22136
  };
22016
22137
  AicoNeoContent.style = AicoNeoContentStyle0;