Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions dotcom-rendering/fixtures/manual/onwardsTrails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import {
ArticleDesign,
ArticleDisplay,
Pillar,
} from '../../src/lib/articleFormat';
import { getDataLinkNameCard } from '../../src/lib/getDataLinkName';
import { type TrailType } from '../../src/types/trails';

export const galleryOnwardsTrails: TrailType[] = [
{
url: 'https://www.theguardian.com/environment/gallery/2025/aug/22/week-in-wildlife-a-clumsy-fox-swinging-orangutang-and-rescued-jaguarundi-cub',
linkText:
'Week in wildlife: a clumsy fox, a swinging orangutan and a rescued jaguarundi cub',
showByline: false,
byline: 'Pejman Faratin',
image: {
src: 'https://media.guim.co.uk/a81e974ffee6c8c88fa280c2d02eaf5dc2af863e/151_292_1020_816/master/1020.jpg',
altText: '',
},
format: {
theme: Pillar.News,
design: ArticleDesign.Gallery,
display: ArticleDisplay.Standard,
},
webPublicationDate: '2022-01-01T06:00:25.000Z',
headline:
'Week in wildlife: a clumsy fox, a swinging orangutan and a rescued jaguarundi cub',
shortUrl: 'https://www.theguardian.com/p/x32n89',
discussion: {
isCommentable: false,
isClosedForComments: true,
discussionId: '/p/x32n89',
},
discussionId: 'zHoBy6HNKsk',
dataLinkName: getDataLinkNameCard(
{
theme: Pillar.News,
design: ArticleDesign.Gallery,
display: ArticleDisplay.Standard,
},
'0',
0,
),
trailText:
'Guinness World Records is looking back at the extraordinary feats achieved since its inception - as well as unveiling 70 whacky and unclaimed records ',
kickerText: 'Politics', // Get data for this
mainMedia: { type: 'Gallery', count: '6' },
},
{
url: 'https://www.theguardian.com/money/gallery/2025/aug/22/characterful-cottages-for-sale-in-england-in-pictures',
linkText: 'Characterful cottages for sale in England – in pictures',
showByline: false,
byline: 'Anna White',
image: {
src: 'https://media.guim.co.uk/58cd9356e6d68e8efa6028162bb959f9798307d5/515_0_5000_4000/master/5000.jpg',
altText: '',
},
format: {
design: ArticleDesign.Gallery,
theme: Pillar.Lifestyle,
display: ArticleDisplay.Standard,
},
webPublicationDate: '2022-01-01T06:00:24.000Z',
headline: 'Characterful cottages for sale in England – in pictures',
shortUrl: 'https://www.theguardian.com/p/x32gqj',
discussion: {
isCommentable: false,
isClosedForComments: true,
discussionId: '/p/x32gqj',
},
dataLinkName: getDataLinkNameCard(
{
design: ArticleDesign.Gallery,
theme: Pillar.Lifestyle,
display: ArticleDisplay.Standard,
},
'0',
1,
),
trailText:
'Picked from a record 60,636 entries, the first images from the Natural History Museum’s wildlife photographer of the year competition have been released. The photographs, which range from a lion facing down a cobra to magnified mould spores, show the diversity, beauty and complexity of the natural world and humanity’s relationship with it',
mainMedia: { type: 'Gallery', count: '6' },
},
{
url: 'https://www.theguardian.com/news/gallery/2025/aug/22/sunsets-aid-parachutes-and-giant-pandas-photos-of-the-day-friday',
linkText:
'Sunsets, aid parachutes and giant pandas: photos of the day – Friday ',
showByline: false,
byline: 'Eithne Staunton',
image: {
src: 'https://media.guim.co.uk/4ce0b080206fe9b65b976c1acf219d81072cc814/0_0_2113_1690/master/2113.png',
altText: '',
},
format: {
design: ArticleDesign.Gallery,
theme: Pillar.News,
display: ArticleDisplay.Standard,
},
webPublicationDate: '2022-01-01T08:49:42.000Z',
headline:
'Sunsets, aid parachutes and giant pandas: photos of the day – Friday ',
shortUrl: 'https://www.theguardian.com/p/x3359z',
discussion: {
isCommentable: false,
isClosedForComments: true,
discussionId: '/p/x3359z',
},
dataLinkName: getDataLinkNameCard(
{
design: ArticleDesign.Gallery,
theme: Pillar.News,
display: ArticleDisplay.Standard,
},
'0',
2,
),
trailText:
'From the mock-Tudor fad of the 1920s to drivers refuelling on a roundabout, each era produces its own distinctive petrol stations – as photographer Philip Butler discovered',
mainMedia: { type: 'Gallery', count: '6' },
},
{
url: 'https://www.theguardian.com/fashion/gallery/2025/aug/22/what-to-wear-to-notting-hill-carnival',
linkText: 'On parade: what to wear to Notting Hill carnival',
showByline: false,
byline: 'Melanie Wilkinson',
image: {
src: 'https://media.guim.co.uk/49a9656cd10c4f64f8bdd54380afb915c7a3648b/207_0_1500_1200/master/1500.jpg',
altText: '',
},
format: {
design: ArticleDesign.Gallery,
theme: Pillar.Lifestyle,
display: ArticleDisplay.Standard,
},
webPublicationDate: '2022-08-22T05:00:23.000Z',
headline: 'On parade: what to wear to Notting Hill carnival',
shortUrl: 'https://www.theguardian.com/p/x32mte',
discussion: {
isCommentable: false,
isClosedForComments: true,
discussionId: '/p/x32mte',
},
dataLinkName: getDataLinkNameCard(
{
design: ArticleDesign.Gallery,
theme: Pillar.Lifestyle,
display: ArticleDisplay.Standard,
},
'0',
1,
),
trailText:
'The Guardian’s picture editors select photographs from around the world',
mainMedia: { type: 'Gallery', count: '6' },
},
{
url: 'https://www.theguardian.com/artanddesign/gallery/2025/aug/21/psychedelic-rock-glass-mountain-michael-lundgren',
linkText:
'Psychedelic rock! Formations that mess with your mind – in pictures ',
showByline: false,
image: {
src: 'https://media.guim.co.uk/2810af61b2d2d2d5f71ec01e56e6555e0a6d4635/55_0_2813_2250/master/2813.jpg',
altText: '',
},
format: {
design: ArticleDesign.Gallery,
theme: Pillar.Culture,
display: ArticleDisplay.Standard,
},
webPublicationDate: '2025-08-21T06:01:01.000Z',
headline:
'Psychedelic rock! Formations that mess with your mind – in pictures ',
shortUrl: 'https://www.theguardian.com/p/x2p663',
discussion: {
isCommentable: false,
isClosedForComments: true,
discussionId: '/p/x2p663',
},
dataLinkName: getDataLinkNameCard(
{
design: ArticleDesign.Gallery,
theme: Pillar.Culture,
display: ArticleDisplay.Standard,
},
'0',
1,
),
trailText:
'Politicians and their partners put on their best show at this year’s Midwinter Ball, an annual dinner hosted by the Federal Parliamentary Press Gallery in Canberra',
mainMedia: { type: 'Gallery', count: '6' },
},
];
44 changes: 37 additions & 7 deletions dotcom-rendering/src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export type Position = 'inner' | 'outer' | 'none';
export type Props = {
linkTo: string;
format: ArticleFormat;
/** The format of the article holding the card */
contextFormat?: ArticleFormat;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prop lets us know which article design the card belongs to when it's displayed as onwards content. Because currently we have a re-design for onward contents cards which is only applied on Gallery articles.

Once the redesign is rolled out to all article types, this prop can be removed.

serverTime?: number;
headlineText: string;
headlineSizes?: ResponsiveFontSize;
Expand Down Expand Up @@ -350,6 +352,7 @@ const liveBulletStyles = css`
export const Card = ({
linkTo,
format,
contextFormat,
headlineText,
headlineSizes,
showQuotedHeadline,
Expand Down Expand Up @@ -551,7 +554,14 @@ export const Card = ({
- */
const isMediaCardOrNewsletter = isMediaCard(format) || isNewsletter;

const showPill = isMediaCardOrNewsletter;
// This is due to a re-design for onwards content.
// Currently this re-design is only applied for galleries secondary onwards content.
// We plan to apply this to all onwards content in the future.
const isGallerySecondaryOnward =
contextFormat?.design === ArticleDesign.Gallery &&
onwardsSource !== 'more-galleries';

const showPill = isMediaCardOrNewsletter && !isGallerySecondaryOnward;

const media = getMedia({
imageUrl: image?.src,
Expand Down Expand Up @@ -594,7 +604,8 @@ export const Card = ({
containerType === 'flexible/special' ||
containerType === 'flexible/general';

const isSmallCard = containerType === 'scrollable/small';
const isSmallCard =
containerType === 'scrollable/small' || isGallerySecondaryOnward;

const hideTrailTextUntil = () => {
if (isFlexibleContainer) {
Expand Down Expand Up @@ -625,6 +636,13 @@ export const Card = ({
* Order matters here as the logic is based on the card properties
*/
const getGapSizes = (): GapSizes => {
if (isGallerySecondaryOnward) {
return {
row: 'medium',
column: 'medium',
};
}

if (isOnwardContent) {
return {
row: 'none',
Expand Down Expand Up @@ -739,7 +757,9 @@ export const Card = ({
onwardContent: boolean,
): 'large' | 'small' | undefined => {
if (mediaCard && betaContainer) return 'large';
if (mediaCard || onwardContent) return 'small';
if ((mediaCard || onwardContent) && !isGallerySecondaryOnward) {
return 'small';
}
return undefined;
};

Expand Down Expand Up @@ -826,6 +846,7 @@ export const Card = ({
showTopBarMobile={showTopBarMobile}
isOnwardContent={isOnwardContent}
containerPalette={containerPalette}
contextFormat={contextFormat}
>
<CardLink
linkTo={linkTo}
Expand Down Expand Up @@ -1062,7 +1083,10 @@ export const Card = ({
loading={imageLoading}
roundedCorners={
isOnwardContent &&
!isMoreGalleriesOnwardContent
!(
isMoreGalleriesOnwardContent ||
isGallerySecondaryOnward
)
}
aspectRatio={aspectRatio}
/>
Expand All @@ -1079,7 +1103,10 @@ export const Card = ({
loading={imageLoading}
roundedCorners={
isOnwardContent &&
!isMoreGalleriesOnwardContent
!(
isMoreGalleriesOnwardContent ||
isGallerySecondaryOnward
)
}
aspectRatio={aspectRatio}
/>
Expand Down Expand Up @@ -1124,7 +1151,10 @@ export const Card = ({
loading={imageLoading}
roundedCorners={
isOnwardContent &&
!isMoreGalleriesOnwardContent
!(
isMoreGalleriesOnwardContent ||
isGallerySecondaryOnward
)
}
aspectRatio="1:1"
/>
Expand Down Expand Up @@ -1155,7 +1185,7 @@ export const Card = ({
padContent={determinePadContent(
isMediaCardOrNewsletter,
isBetaContainer,
isOnwardContent && !isMoreGalleriesOnwardContent,
isOnwardContent,
)}
>
{/* This div is needed to keep the headline and trail text justified at the start */}
Expand Down
26 changes: 17 additions & 9 deletions dotcom-rendering/src/components/Card/components/CardWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Props = {
showTopBarMobile: boolean;
isOnwardContent: boolean;
containerPalette?: DCRContainerPalette;
contextFormat?: ArticleFormat;
};

const baseCardStyles = css`
Expand Down Expand Up @@ -72,24 +73,27 @@ const hoverStyles = css`
}
`;

const topBarStyles = css`
const topBarStyles = (isOnwardContent: boolean) => css`
::before {
border-top: 1px solid ${palette('--card-border-top')};
border-top: 1px solid
${isOnwardContent
? palette('--onward-content-border')
: palette('--card-border-top')};
Copy link
Contributor Author

@marjisound marjisound Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of this change, all the Card stories are showing diffs in the Chromatic snapshots. The visual design hasn’t changed, only the generated Emotion class names have.

content: '';
z-index: 2;
width: 100%;
padding-bottom: ${space[2]}px;
background-color: unset;
}
`;
const mobileTopBarStyles = css`
const mobileTopBarStyles = (isOnwardContent: boolean) => css`
${until.tablet} {
${topBarStyles}
${topBarStyles(isOnwardContent)}
}
`;
const desktopTopBarStyles = css`
const desktopTopBarStyles = (isOnwardContent: boolean) => css`
${from.tablet} {
${topBarStyles}
${topBarStyles(isOnwardContent)}
}
`;

Expand All @@ -109,18 +113,22 @@ export const CardWrapper = ({
showTopBarMobile,
isOnwardContent,
containerPalette,
contextFormat,
}: Props) => {
const isGalleryContext = contextFormat?.design === ArticleDesign.Gallery;
return (
<FormatBoundary format={format}>
<ContainerOverrides containerPalette={containerPalette}>
<div
css={[
baseCardStyles,
hoverStyles,
showTopBarDesktop && desktopTopBarStyles,
showTopBarMobile && mobileTopBarStyles,
showTopBarDesktop &&
desktopTopBarStyles(isGalleryContext),
showTopBarMobile &&
mobileTopBarStyles(isGalleryContext),
isOnwardContent &&
format.design !== ArticleDesign.Gallery &&
!isGalleryContext &&
onwardContentStyles,
]}
>
Expand Down
Loading
Loading