diff --git a/dotcom-rendering/src/components/ArticlePage.tsx b/dotcom-rendering/src/components/ArticlePage.tsx index a5b9d8eaf06..0db8a8f6d86 100644 --- a/dotcom-rendering/src/components/ArticlePage.tsx +++ b/dotcom-rendering/src/components/ArticlePage.tsx @@ -4,6 +4,7 @@ import { DecideLayout } from '../layouts/DecideLayout'; import { buildAdTargeting } from '../lib/ad-targeting'; import { ArticleDesign } from '../lib/articleFormat'; import { rootStyles } from '../lib/rootStyles'; +import { isFilterPageId } from '../lib/theFilter'; import type { NavType } from '../model/extract-nav'; import type { Article } from '../types/article'; import type { RenderingTarget } from '../types/renderingTarget'; @@ -78,6 +79,7 @@ export const ArticlePage = (props: WebProps | AppProps) => { ; }; const fullWidthStyle = css` @@ -56,6 +57,7 @@ export const ProductLinkButton = ({ priority = 'primary', dataComponent, xCustComponentId, + themeOverrides, }: ProductLinkButtonProps) => { const cssOverrides: SerializedStyles[] = [ heightAutoStyle, @@ -69,7 +71,7 @@ export const ProductLinkButton = ({ href={url} rel={SKIMLINK_REL} priority={priority} - theme={theme} + theme={{ ...theme, ...themeOverrides }} data-component={dataComponent} data-ignore="global-link-styling" data-link-name={`product link button ${priority}`} diff --git a/dotcom-rendering/src/components/HorizontalSummaryProductCard.tsx b/dotcom-rendering/src/components/HorizontalSummaryProductCard.tsx index 6c1a38e8b13..f715bdea1c6 100644 --- a/dotcom-rendering/src/components/HorizontalSummaryProductCard.tsx +++ b/dotcom-rendering/src/components/HorizontalSummaryProductCard.tsx @@ -95,6 +95,7 @@ export const HorizontalSummaryProductCard = ({ diff --git a/dotcom-rendering/src/components/HostedContentPage.tsx b/dotcom-rendering/src/components/HostedContentPage.tsx index f95ae6b3d3e..d6a8c9f9c19 100644 --- a/dotcom-rendering/src/components/HostedContentPage.tsx +++ b/dotcom-rendering/src/components/HostedContentPage.tsx @@ -5,6 +5,7 @@ import { HostedGalleryLayout } from '../layouts/HostedGalleryLayout'; import { HostedVideoLayout } from '../layouts/HostedVideoLayout'; import { ArticleDesign } from '../lib/articleFormat'; import { rootStyles } from '../lib/rootStyles'; +import { isFilterPageId } from '../lib/theFilter'; import type { Article } from '../types/article'; import type { RenderingTarget } from '../types/renderingTarget'; import { AlreadyVisited } from './AlreadyVisited.island'; @@ -91,6 +92,7 @@ export const HostedContentPage = (props: WebProps | AppProps) => { { @@ -92,6 +92,49 @@ export const WithCredit = { }, } satisfies Story; +const testProductCtas: ProductCta[] = [ + { + url: 'https://example.com/buy-1', + text: '', + retailer: 'Amazon', + price: '£19.99', + }, + { + url: 'https://example.com/buy-2', + text: '', + retailer: 'John Lewis', + price: '£21.00', + }, +]; + +export const WithProductCtas = { + args: { + format: { + display: ArticleDisplay.Standard, + design: ArticleDesign.Standard, + theme: Pillar.News, + }, + images: [ + { ...testImage, title: 'Title', productCtas: testProductCtas }, + ], + isFilterArticle: true, + }, +} satisfies Story; + +export const WithProductCtasNonFilterArticle = { + args: { + format: { + display: ArticleDisplay.Standard, + design: ArticleDesign.Standard, + theme: Pillar.News, + }, + images: [ + { ...testImage, title: 'Title', productCtas: testProductCtas }, + ], + isFilterArticle: false, + }, +} satisfies Story; + export const WithRating = { args: { format: { diff --git a/dotcom-rendering/src/components/Lightbox.tsx b/dotcom-rendering/src/components/Lightbox.tsx index 356d8fbb72a..906637697d0 100644 --- a/dotcom-rendering/src/components/Lightbox.tsx +++ b/dotcom-rendering/src/components/Lightbox.tsx @@ -12,6 +12,7 @@ interface BaseProps { format: ArticleFormat; renderingTarget: RenderingTarget; switches: Switches; + isFilterArticle: boolean; } interface WebProps extends BaseProps { @@ -29,6 +30,7 @@ export const Lightbox = ({ lightboxImages, renderingTarget, switches, + isFilterArticle, }: WebProps | AppProps) => { switch (renderingTarget) { case 'Web': @@ -46,6 +48,7 @@ export const Lightbox = ({ diff --git a/dotcom-rendering/src/components/LightboxImages.tsx b/dotcom-rendering/src/components/LightboxImages.tsx index f24d2e26607..fca05593001 100644 --- a/dotcom-rendering/src/components/LightboxImages.tsx +++ b/dotcom-rendering/src/components/LightboxImages.tsx @@ -16,11 +16,13 @@ import type { ImageForLightbox } from '../types/content'; import { LightboxCaption } from './LightboxCaption'; import { LightboxLoader } from './LightboxLoader'; import { Picture } from './Picture'; +import { ProductCardButtons } from './ProductCardButtons'; import { StarRating } from './StarRating/StarRating'; type Props = { format: ArticleFormat; images: ImageForLightbox[]; + isFilterArticle?: boolean; }; const liStyles = css` @@ -134,6 +136,16 @@ const starRatingMarginStyles = css` margin-bottom: ${space[3]}px; } `; + +const productCtasStyles = css` + display: flex; + flex-direction: column; + gap: ${space[1]}px; + margin-bottom: ${space[2]}px; + ${from.tablet} { + margin-bottom: ${space[3]}px; + } +`; const Selection = ({ countOfImages, initialPosition = 1, @@ -179,7 +191,11 @@ const Selection = ({ ); }; -export const LightboxImages = ({ format, images }: Props) => { +export const LightboxImages = ({ + format, + images, + isFilterArticle = false, +}: Props) => { const [loaded, setLoaded] = useState(new Set()); useEffect(() => { @@ -200,6 +216,11 @@ export const LightboxImages = ({ format, images }: Props) => { return previousSize !== newSize ? new Set(set) : set; }); + const hasProductCtas = !!image.productCtas?.length; + // The "show info without needing to click 'i'" override is + // currently scoped to Filter articles only. + const alwaysShowInfo = hasProductCtas && isFilterArticle; + return (
  • { onLoad={onLoad} loading="lazy" /> -