Skip to content

Commit 766ea33

Browse files
add not showing headline
1 parent 8240e4d commit 766ea33

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

dotcom-rendering/src/components/ProductElement.stories.tsx

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const ArticleElementComponent = getNestedArticleElement({
2222
const product: ProductBlockElement = {
2323
_type: 'model.dotcomrendering.pageElements.ProductBlockElement',
2424
elementId: 'b1f6e8e2-3f3a-4f0c-8d1e-5f3e3e3e3e3e',
25-
primaryHeading: 'Best fan overall',
25+
primaryHeading: '<em>Best fan overall</em>',
2626
secondaryHeading: 'AirCraft Lume',
2727
brandName: 'AirCraft',
2828
productName: 'Lume',
@@ -467,6 +467,39 @@ export default meta;
467467

468468
export const Default = {};
469469

470+
export const withoutHeading: StoryFn = () => {
471+
return (
472+
<>
473+
<ProductElement
474+
product={{
475+
...product,
476+
primaryHeading: '',
477+
secondaryHeading: '',
478+
}}
479+
format={{
480+
design: ArticleDesign.Review,
481+
display: ArticleDisplay.Showcase,
482+
theme: Pillar.Lifestyle,
483+
}}
484+
ArticleElementComponent={ArticleElementComponent}
485+
/>
486+
<ProductElement
487+
product={{
488+
...product,
489+
primaryHeading: `<em></em>`,
490+
secondaryHeading: `<strong></strong>`,
491+
}}
492+
format={{
493+
design: ArticleDesign.Review,
494+
display: ArticleDisplay.Showcase,
495+
theme: Pillar.Lifestyle,
496+
}}
497+
ArticleElementComponent={ArticleElementComponent}
498+
/>
499+
</>
500+
);
501+
};
502+
470503
export const MultipleProducts: StoryFn = () => {
471504
return (
472505
<>

dotcom-rendering/src/components/ProductElement.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import { css } from '@emotion/react';
22
import { from } from '@guardian/source/foundations';
33
import type { ReactNode } from 'react';
44
import type { ArticleFormat } from '../lib/articleFormat';
5+
import { parseHtml } from '../lib/domUtils';
56
import type { NestedArticleElement } from '../lib/renderElement';
67
import type { FEElement, ProductBlockElement } from '../types/content';
78
import { InlineProductCard } from './InlineProductCard';
89
import { LeftColProductCard } from './LeftColProductCard';
9-
import { SubheadingBlockComponent } from './SubheadingBlockComponent';
10+
import { buildElementTree } from './SubheadingBlockComponent';
1011

1112
export type Product = {
1213
primaryHeadline: string;
@@ -51,16 +52,26 @@ export const ProductElement = ({
5152
ArticleElementComponent: NestedArticleElement;
5253
format: ArticleFormat;
5354
}) => {
54-
const subheadingHtml = `<h2>${product.primaryHeading || ''} ${
55-
product.secondaryHeading || ''
56-
}</h2>`;
55+
const subheadingHtml = parseHtml(
56+
`<h2 id="${product.h2Id ?? product.elementId}">${
57+
product.primaryHeading || ''
58+
} ${product.secondaryHeading || ''}</h2>`,
59+
);
60+
61+
const isSubheading = subheadingHtml.textContent
62+
? subheadingHtml.textContent.trim().length > 0
63+
: false;
64+
5765
return (
5866
<div
5967
css={css`
6068
position: relative;
6169
`}
6270
>
63-
<SubheadingBlockComponent html={subheadingHtml} format={format} />
71+
{isSubheading &&
72+
Array.from(subheadingHtml.childNodes).map(
73+
buildElementTree(format),
74+
)}
6475
<LeftColProductCardContainer>
6576
<LeftColProductCard
6677
brandName={product.brandName}

dotcom-rendering/src/model/enhance-H2s.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { JSDOM } from 'jsdom';
2-
import type { FEElement, SubheadingBlockElement } from '../types/content';
2+
import type { FEElement } from '../types/content';
33
import { isLegacyTableOfContents } from './isLegacyTableOfContents';
44

55
const shouldUseLegacyIDs = (elements: FEElement[]): boolean => {
@@ -11,8 +11,8 @@ const shouldUseLegacyIDs = (elements: FEElement[]): boolean => {
1111
);
1212
};
1313

14-
const extractText = (element: SubheadingBlockElement): string => {
15-
const frag = JSDOM.fragment(element.html);
14+
export const extractText = (html: string): string => {
15+
const frag = JSDOM.fragment(html);
1616
if (!frag.firstElementChild) return '';
1717
return frag.textContent?.trim() ?? '';
1818
};
@@ -47,11 +47,11 @@ export const slugify = (text: string): string => {
4747
/**
4848
* This function attempts to create a slugified string to use as the id. It fails over to elementId.
4949
*/
50-
const generateId = (element: SubheadingBlockElement, existingIds: string[]) => {
51-
const text = extractText(element);
52-
if (!text) return element.elementId;
50+
const generateId = (elementId: string, html: string, existingIds: string[]) => {
51+
const text = extractText(html);
52+
if (!text) return elementId;
5353
const slug = slugify(text);
54-
if (!slug) return element.elementId;
54+
if (!slug) return elementId;
5555
const unique = getUnique(slug, existingIds);
5656
existingIds.push(slug);
5757
return unique;
@@ -71,7 +71,7 @@ export const enhanceH2s = (elements: FEElement[]): FEElement[] => {
7171
) {
7272
const id = shouldUseElementId
7373
? element.elementId
74-
: generateId(element, slugifiedIds);
74+
: generateId(element.elementId, element.html, slugifiedIds);
7575

7676
const withId = element.html.replace(
7777
'<h2>',
@@ -82,6 +82,19 @@ export const enhanceH2s = (elements: FEElement[]): FEElement[] => {
8282
...element,
8383
html: withId,
8484
};
85+
} else if (
86+
element._type ===
87+
'model.dotcomrendering.pageElements.ProductBlockElement'
88+
) {
89+
const subheadingHtml = `${element.primaryHeading || ''} ${
90+
element.secondaryHeading || ''
91+
}`;
92+
93+
const h2Id = shouldUseElementId
94+
? element.elementId
95+
: generateId(element.elementId, subheadingHtml, slugifiedIds);
96+
97+
return { ...element, h2Id };
8598
} else {
8699
// Otherwise, do nothing
87100
return element;

dotcom-rendering/src/types/content.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ export interface ProductBlockElement {
488488
secondaryCta: string;
489489
statistics: { name: string; value: string }[];
490490
content: FEElement[];
491+
h2Id?: string;
491492
}
492493

493494
interface ProfileAtomBlockElement {

0 commit comments

Comments
 (0)