Skip to content

Commit a901d4f

Browse files
committed
Merge branch 'main' into add-gallery-lightbox
2 parents 7900e46 + 3a2b0ed commit a901d4f

17 files changed

+286
-162
lines changed

dotcom-rendering/fixtures/manual/trails.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ export const audioTrails: [DCRFrontCard, DCRFrontCard] = [
469469
altText:
470470
"TOPSHOT-FBL-EUR-C1-MILAN-FEYENOORD<br>TOPSHOT - Polish referee Szymon Marciniak gives a red card to AC Milan's French defender #19 Theo Hernandez (R) during the UEFA Champions League knockout round play-off second leg football match between AC Milan and Feyenoord at San Siro stadium in Milan, on February 18, 2025. (Photo by Piero CRUCIATTI / AFP) (Photo by PIERO CRUCIATTI/AFP via Getty Images)",
471471
},
472+
supportingContent: getSublinks(2),
472473
},
473474
];
474475

@@ -541,6 +542,7 @@ export const galleryTrails: [DCRFrontCard, DCRFrontCard] = [
541542
src: 'https://media.guim.co.uk/69ac2383ea611126b54373865dac3e7e77981d7e/0_39_5500_3302/master/5500.jpg',
542543
altText: 'A group of people in the street, some looking worried',
543544
},
545+
supportingContent: getSublinks(2),
544546
},
545547
];
546548

dotcom-rendering/src/components/AffiliateDisclaimer.tsx

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { css } from '@emotion/react';
22
import {
33
palette,
44
space,
5+
textSans12,
56
textSans14,
67
textSans15,
78
} from '@guardian/source/foundations';
@@ -20,6 +21,23 @@ const disclaimerLeftColStyles = css`
2021
padding-bottom: ${space[1]}px;
2122
`;
2223

24+
const galleryDisclaimerStyles = css`
25+
${textSans12};
26+
line-height: 1.5;
27+
color: ${themePalette('--affiliate-disclaimer-text')};
28+
a {
29+
color: ${themePalette('--affiliate-disclaimer-text')};
30+
transition: border-color 0.15s ease-out;
31+
border-bottom: 1px solid ${palette.neutral[46]};
32+
text-decoration: none;
33+
}
34+
a:hover {
35+
border-bottom: 1px solid
36+
${themePalette('--affiliate-disclaimer-text-hover')};
37+
text-decoration: none;
38+
}
39+
`;
40+
2341
const disclaimerInlineStyles = css`
2442
${textSans14};
2543
/**
@@ -64,8 +82,9 @@ const DisclaimerText = () => (
6482
The Guardian’s journalism is independent. We will earn a commission if
6583
you buy something through an affiliate link.&nbsp;
6684
<a href="https://www.theguardian.com/info/2017/nov/01/reader-information-on-affiliate-links">
67-
Learn more.
85+
Learn more
6886
</a>
87+
.
6988
</p>
7089
);
7190

@@ -99,4 +118,17 @@ const AffiliateDisclaimerInline = ({ isAmp = false }) =>
99118
</Hide>
100119
);
101120

102-
export { AffiliateDisclaimer, AffiliateDisclaimerInline };
121+
const GalleryAffiliateDisclaimer = () => (
122+
<aside
123+
css={[disclaimerLeftColStyles, galleryDisclaimerStyles]}
124+
data-testid="affiliate-disclaimer"
125+
>
126+
<DisclaimerText />
127+
</aside>
128+
);
129+
130+
export {
131+
AffiliateDisclaimer,
132+
AffiliateDisclaimerInline,
133+
GalleryAffiliateDisclaimer,
134+
};

dotcom-rendering/src/components/ArticleMeta.web.tsx

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { css } from '@emotion/react';
22
import { between, from, space, until } from '@guardian/source/foundations';
33
import { StraightLines } from '@guardian/source-development-kitchen/react-components';
4-
import { grid } from '../../src/grid';
54
import type { FEArticle } from '../frontend/feArticle';
65
import { interactiveLegacyClasses } from '../layouts/lib/interactiveLegacyStyling';
76
import {
@@ -184,28 +183,11 @@ export const metaContainer = (format: ArticleFormat) => {
184183
}
185184
`;
186185
case ArticleDesign.LiveBlog:
187-
case ArticleDesign.DeadBlog: {
186+
case ArticleDesign.DeadBlog:
187+
case ArticleDesign.Gallery: {
188188
return '';
189189
}
190-
case ArticleDesign.Gallery:
191-
return css`
192-
${grid.column.centre}
193-
padding-bottom: ${space[3]}px;
194-
${from.tablet} {
195-
position: relative;
196-
&::before {
197-
content: '';
198-
position: absolute;
199-
left: -10px;
200-
top: 0;
201-
bottom: 0;
202-
width: 1px;
203-
background-color: ${themePalette(
204-
'--article-border',
205-
)};
206-
}
207-
}
208-
`;
190+
209191
default:
210192
return defaultMargins;
211193
}

dotcom-rendering/src/components/Caption.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { css } from '@emotion/react';
22
import {
3+
between,
34
from,
45
space,
56
textSans12,
@@ -211,10 +212,24 @@ const captionLink = css`
211212

212213
const galleryStyles = css`
213214
${grid.column.centre}
215+
margin-bottom: 0;
216+
padding-bottom: 6px;
214217
${from.leftCol} {
215218
${grid.column.left}
216219
grid-row-start: 8;
217220
}
221+
${between.tablet.and.leftCol} {
222+
position: relative;
223+
&::before {
224+
content: '';
225+
position: absolute;
226+
left: -10px;
227+
top: 0;
228+
bottom: 0;
229+
width: 1px;
230+
background-color: ${palette('--article-border')};
231+
}
232+
}
218233
`;
219234

220235
const CameraIcon = ({ format }: IconProps) => {

dotcom-rendering/src/components/CaptionText.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { css } from '@emotion/react';
22
import { headlineMedium17, space } from '@guardian/source/foundations';
33
import { type ReactNode } from 'react';
44
import sanitise, { type IOptions } from 'sanitize-html';
5+
import { isSkimlink } from '../lib/affiliateLinksUtils';
56
import { getAttrs, parseHtml } from '../lib/domUtils';
67
import { palette } from '../palette';
78

@@ -38,6 +39,7 @@ const renderTextElement = (node: Node, key: number): ReactNode => {
3839
return text === '' ? null : <em key={key}>{children}</em>;
3940
case 'A': {
4041
const attrs = getAttrs(node);
42+
const href = attrs?.getNamedItem('href')?.value;
4143

4244
return (
4345
<a
@@ -51,7 +53,7 @@ const renderTextElement = (node: Node, key: number): ReactNode => {
5153
${palette('--article-link-border-hover')};
5254
}
5355
`}
54-
href={attrs?.getNamedItem('href')?.value}
56+
href={href}
5557
target={attrs?.getNamedItem('target')?.value}
5658
data-link-name={
5759
attrs?.getNamedItem('data-link-name')?.value
@@ -60,6 +62,11 @@ const renderTextElement = (node: Node, key: number): ReactNode => {
6062
attrs?.getNamedItem('data-component')?.value
6163
}
6264
key={key}
65+
/**
66+
* Affiliate links must have the rel attribute set to "sponsored"
67+
* @see https://developers.google.com/search/docs/crawling-indexing/qualify-outbound-links
68+
*/
69+
rel={isSkimlink(href) ? 'sponsored' : undefined}
6370
>
6471
{children}
6572
</a>

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

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import {
99
Pillar,
1010
} from '../../lib/articleFormat';
1111
import type { Branding } from '../../types/branding';
12-
import type { DCRContainerPalette } from '../../types/front';
12+
import type {
13+
DCRContainerPalette,
14+
DCRSupportingContent,
15+
} from '../../types/front';
1316
import type { MainMedia } from '../../types/mainMedia';
1417
import { ContainerOverrides } from '../ContainerOverrides';
1518
import { FrontSection } from '../FrontSection';
@@ -80,6 +83,19 @@ const mainGallery: MainMedia = {
8083
count: '5',
8184
};
8285

86+
const twoSublinks: DCRSupportingContent[] = [
87+
{
88+
...aBasicLink,
89+
headline: 'Headline 1',
90+
kickerText: 'Kicker',
91+
},
92+
{
93+
...aBasicLink,
94+
headline: 'Headline 2',
95+
kickerText: 'Kicker',
96+
},
97+
];
98+
8399
const CardWrapper = ({ children }: { children: React.ReactNode }) => {
84100
return (
85101
<div
@@ -345,23 +361,48 @@ export const WithMediaTypeAndSublinks = () => {
345361
design: ArticleDesign.Video,
346362
theme: Pillar.Sport,
347363
}}
348-
containerType="flexible/general"
349364
mainMedia={{ ...mainVideo, duration: 30 }}
350365
headlineText="Video"
351-
imagePositionOnDesktop="top"
352-
imagePositionOnMobile="left"
353-
supportingContent={[
354-
{
355-
...aBasicLink,
356-
headline: 'Headline 1',
357-
kickerText: 'Kicker',
358-
},
359-
{
360-
...aBasicLink,
361-
headline: 'Headline 2',
362-
kickerText: 'Kicker',
363-
},
364-
]}
366+
supportingContent={twoSublinks}
367+
/>
368+
</CardWrapper>
369+
<CardWrapper>
370+
<Card
371+
{...basicCardProps}
372+
format={{
373+
display: ArticleDisplay.Standard,
374+
design: ArticleDesign.Video,
375+
theme: Pillar.Sport,
376+
}}
377+
mainMedia={{ ...mainVideo, duration: 0 }}
378+
headlineText="Video without duration"
379+
supportingContent={twoSublinks}
380+
/>
381+
</CardWrapper>
382+
<CardWrapper>
383+
<Card
384+
{...basicCardProps}
385+
format={{
386+
display: ArticleDisplay.Standard,
387+
design: ArticleDesign.Audio,
388+
theme: Pillar.Sport,
389+
}}
390+
mainMedia={mainAudio}
391+
headlineText="Audio"
392+
supportingContent={twoSublinks}
393+
/>
394+
</CardWrapper>
395+
<CardWrapper>
396+
<Card
397+
{...basicCardProps}
398+
format={{
399+
display: ArticleDisplay.Standard,
400+
design: ArticleDesign.Gallery,
401+
theme: Pillar.Sport,
402+
}}
403+
mainMedia={mainGallery}
404+
headlineText="Gallery"
405+
supportingContent={twoSublinks}
365406
/>
366407
</CardWrapper>
367408
</CardGroup>
@@ -1764,18 +1805,7 @@ export const WithBetaContainerAndSublinks = () => {
17641805
{...basicCardProps}
17651806
containerType="flexible/general"
17661807
imagePositionOnMobile="bottom"
1767-
supportingContent={[
1768-
{
1769-
...aBasicLink,
1770-
headline: 'Headline 1',
1771-
kickerText: 'Kicker',
1772-
},
1773-
{
1774-
...aBasicLink,
1775-
headline: 'Headline 2',
1776-
kickerText: 'Kicker',
1777-
},
1778-
]}
1808+
supportingContent={twoSublinks}
17791809
/>
17801810
</CardWrapper>
17811811
</CardGroup>
@@ -1791,18 +1821,7 @@ export const WithBetaContainerAndSublinksNoImage = () => {
17911821
image={undefined}
17921822
containerType="flexible/general"
17931823
imagePositionOnMobile="bottom"
1794-
supportingContent={[
1795-
{
1796-
...aBasicLink,
1797-
headline: 'Headline 1',
1798-
kickerText: 'Kicker',
1799-
},
1800-
{
1801-
...aBasicLink,
1802-
headline: 'Headline 2',
1803-
kickerText: 'Kicker',
1804-
},
1805-
]}
1824+
supportingContent={twoSublinks}
18061825
/>
18071826
</CardWrapper>
18081827
</CardGroup>

dotcom-rendering/src/components/Card/components/CardLayout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type Props = {
2323

2424
const containerStyles = css`
2525
display: flex;
26+
position: relative;
2627
flex-basis: 100%;
2728
`;
2829

0 commit comments

Comments
 (0)