From 909df92b60421194397bacdd87663526ff51d69e Mon Sep 17 00:00:00 2001 From: Dominik Lander Date: Tue, 28 Oct 2025 09:12:48 +0000 Subject: [PATCH 1/4] Don't fix podcast image width when card is horizontal --- dotcom-rendering/src/components/Card/Card.tsx | 60 +++++++++++-------- .../Card/components/MediaWrapper.tsx | 9 +++ .../components/ScrollableSmall.importable.tsx | 1 + 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/dotcom-rendering/src/components/Card/Card.tsx b/dotcom-rendering/src/components/Card/Card.tsx index 85114b25984..9449604eadb 100644 --- a/dotcom-rendering/src/components/Card/Card.tsx +++ b/dotcom-rendering/src/components/Card/Card.tsx @@ -227,33 +227,37 @@ const HorizontalDivider = () => ( /> ); -const podcastImageStyles = (imageSize: MediaSizeType) => { - switch (imageSize) { - case 'scrollable-small': - return css` - width: 69px; - height: 69px; - ${from.tablet} { - width: 98px; - height: 98px; - } - `; - - case 'scrollable-medium': - return css` +const podcastImageStyles = ( + fixImageWidth: boolean, + imagePositionOnDesktop: MediaPositionType, +) => { + if (fixImageWidth) { + return css` + width: 69px; + height: 69px; + ${from.tablet} { width: 98px; height: 98px; - ${from.tablet} { - width: 120px; - height: 120px; - } - `; - default: - return css` + } + `; + } + + if ( + imagePositionOnDesktop === 'top' || + imagePositionOnDesktop === 'bottom' + ) { + return css` + width: 98px; + height: 98px; + ${from.tablet} { width: 120px; height: 120px; - `; + } + `; } + + // Don't fix the image width if the image is horizontal on desktop + return undefined; }; const getMedia = ({ @@ -908,8 +912,9 @@ export const Card = ({ mediaPositionOnMobile={mediaPositionOnMobile} fixImageWidth={ fixImageWidth ?? - (mediaPositionOnMobile === 'left' || - mediaPositionOnMobile === 'right') + (!isBetaContainer && + (mediaPositionOnMobile === 'left' || + mediaPositionOnMobile === 'right')) } hideImageOverlay={media.type === 'slideshow'} padMedia={isMediaCardOrNewsletter && isBetaContainer} @@ -1119,7 +1124,12 @@ export const Card = ({ {media.type === 'podcast' && ( <> {media.podcastImage?.src && !showKickerImage ? ( -
+
); From 0c7d6215b3d18ebee69e872f03b0e445ba3e9bc0 Mon Sep 17 00:00:00 2001 From: Dominik Lander Date: Wed, 29 Oct 2025 10:31:58 +0000 Subject: [PATCH 2/4] Refactor Podcast image styling --- dotcom-rendering/src/components/Card/Card.tsx | 69 ++++---------- .../Card/components/MediaWrapper.tsx | 90 +++++++++---------- .../components/ScrollableSmall.importable.tsx | 1 - 3 files changed, 64 insertions(+), 96 deletions(-) diff --git a/dotcom-rendering/src/components/Card/Card.tsx b/dotcom-rendering/src/components/Card/Card.tsx index 9449604eadb..85ae6ece5ef 100644 --- a/dotcom-rendering/src/components/Card/Card.tsx +++ b/dotcom-rendering/src/components/Card/Card.tsx @@ -66,7 +66,6 @@ import { CardWrapper } from './components/CardWrapper'; import { ContentWrapper } from './components/ContentWrapper'; import { HeadlineWrapper } from './components/HeadlineWrapper'; import type { - MediaFixedSizeOptions, MediaPositionType, MediaSizeType, } from './components/MediaWrapper'; @@ -157,7 +156,6 @@ export type Props = { trailTextSize?: TrailTextSize; /** A kicker image is seperate to the main media and renders as part of the kicker */ showKickerImage?: boolean; - fixImageWidth?: boolean; /** Determines if the headline should be positioned within the content or outside the content */ headlinePosition?: 'inner' | 'outer'; /** Feature flag for the labs redesign work */ @@ -228,10 +226,10 @@ const HorizontalDivider = () => ( ); const podcastImageStyles = ( - fixImageWidth: boolean, + isSmallCard: boolean, imagePositionOnDesktop: MediaPositionType, ) => { - if (fixImageWidth) { + if (isSmallCard) { return css` width: 69px; height: 69px; @@ -242,22 +240,17 @@ const podcastImageStyles = ( `; } - if ( - imagePositionOnDesktop === 'top' || - imagePositionOnDesktop === 'bottom' - ) { - return css` - width: 98px; - height: 98px; - ${from.tablet} { - width: 120px; - height: 120px; - } - `; - } + const isHorizontalOnDesktop = + imagePositionOnDesktop === 'left' || imagePositionOnDesktop === 'right'; - // Don't fix the image width if the image is horizontal on desktop - return undefined; + return css` + width: 98px; + height: 98px; + ${from.tablet} { + width: ${isHorizontalOnDesktop ? 'unset' : '120px'}; + height: ${isHorizontalOnDesktop ? 'unset' : '120px'}; + } + `; }; const getMedia = ({ @@ -403,7 +396,6 @@ export const Card = ({ showTopBarMobile = true, trailTextSize, showKickerImage = false, - fixImageWidth, headlinePosition = 'inner', showLabsRedesign = false, }: Props) => { @@ -590,27 +582,7 @@ export const Card = ({ containerType === 'flexible/special' || containerType === 'flexible/general'; - const isSmallCard = - containerType === 'scrollable/small' || - containerType === 'scrollable/medium'; - - const mediaFixedSizeOptions = (): MediaFixedSizeOptions => { - if (isSmallCard) { - return { - mobile: 'tiny', - tablet: 'small', - desktop: 'small', - }; - } - - if (isFlexibleContainer) { - return { - mobile: 'small', - }; - } - - return { mobile: 'medium' }; - }; + const isSmallCard = containerType === 'scrollable/small'; const hideTrailTextUntil = () => { if (isFlexibleContainer) { @@ -664,7 +636,10 @@ export const Card = ({ return { row: 'small', column: 'small' }; } - if (isSmallCard) { + if ( + containerType === 'scrollable/small' || + containerType === 'scrollable/medium' + ) { return { row: 'medium', column: 'medium', @@ -906,19 +881,13 @@ export const Card = ({ {media && ( {media.type === 'slideshow' && (
diff --git a/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx b/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx index 2fc81295929..8d8cbe5a981 100644 --- a/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx +++ b/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx @@ -9,14 +9,6 @@ const mediaFixedSize = { medium: 125, }; -type MediaFixedSize = keyof typeof mediaFixedSize; - -export type MediaFixedSizeOptions = { - mobile?: MediaFixedSize; - tablet?: MediaFixedSize; - desktop?: MediaFixedSize; -}; - export type MediaPositionType = 'left' | 'top' | 'right' | 'bottom' | 'none'; export type MediaSizeType = | 'small' @@ -36,18 +28,17 @@ export type MediaSizeType = type Props = { children: React.ReactNode; mediaSize: MediaSizeType; - mediaFixedSizes?: MediaFixedSizeOptions; mediaType?: CardMediaType; mediaPositionOnDesktop: MediaPositionType; mediaPositionOnMobile: MediaPositionType; - fixImageWidth: boolean; /** * Forces hiding the image overlay added to pictures & slideshows on hover. * This is to allow hiding the overlay on slideshow carousels where we don't * want it to be shown whilst retaining it for existing slideshows. */ hideImageOverlay?: boolean; - isBetaContainer?: boolean; + isBetaContainer: boolean; + isSmallCard: boolean; padMedia?: boolean; }; @@ -150,6 +141,7 @@ const flexBasisStyles = ({ `; } }; + /** * Below tablet, we fix the size of the media and add a margin around it. * The corresponding content flex grows to fill the space. @@ -163,43 +155,48 @@ const fixMediaWidthStyles = (width: number) => css` align-self: flex-start; `; -const fixMediaWidth = ({ - mobile, - tablet, - desktop, -}: MediaFixedSizeOptions) => css` - ${mobile && - css` +const fixMobileMediaWidth = ( + isBetaContainer: boolean, + isSmallCard: boolean, +) => { + if (!isBetaContainer) { + return css` + ${until.tablet} { + ${fixMediaWidthStyles(mediaFixedSize.medium)} + } + `; + } + + const size = isSmallCard ? mediaFixedSize.tiny : mediaFixedSize.small; + + return css` ${until.tablet} { - ${fixMediaWidthStyles(mediaFixedSize[mobile])} - } - `} - ${tablet && - css` - ${between.tablet.and.desktop} { - ${fixMediaWidthStyles(mediaFixedSize[tablet])} + ${fixMediaWidthStyles(size)} } - `} - ${desktop && - css` - ${from.desktop} { - ${fixMediaWidthStyles(mediaFixedSize[desktop])} + `; +}; + +const fixDesktopMediaWidth = () => { + return css` + ${from.tablet} { + ${fixMediaWidthStyles(mediaFixedSize.small)} } - `} -`; + `; +}; export const MediaWrapper = ({ children, mediaSize, - mediaFixedSizes = { mobile: 'medium' }, mediaType, mediaPositionOnDesktop, mediaPositionOnMobile, - fixImageWidth, hideImageOverlay, - isBetaContainer = false, + isBetaContainer, + isSmallCard, padMedia, }: Props) => { + const isHorizontalOnMobile = + mediaPositionOnMobile === 'left' || mediaPositionOnMobile === 'right'; const isHorizontalOnDesktop = mediaPositionOnDesktop === 'left' || mediaPositionOnDesktop === 'right'; @@ -215,15 +212,6 @@ export const MediaWrapper = ({ mediaSize, isBetaContainer, }), - mediaType === 'podcast' && - isHorizontalOnDesktop && - !fixImageWidth && - css` - flex-basis: 120px; - ${from.desktop} { - flex-basis: 168px; - } - `, mediaType === 'avatar' && css` display: flex; @@ -236,7 +224,19 @@ export const MediaWrapper = ({ display: none; } `, - fixImageWidth && fixMediaWidth(mediaFixedSizes), + isHorizontalOnMobile && + mediaType !== 'podcast' && + fixMobileMediaWidth(isBetaContainer, isSmallCard), + isSmallCard && fixDesktopMediaWidth(), + mediaType === 'podcast' && + isHorizontalOnDesktop && + !isSmallCard && + css` + flex-basis: 120px; + ${from.desktop} { + flex-basis: 168px; + } + `, isHorizontalOnDesktop && css` ${from.tablet} { diff --git a/dotcom-rendering/src/components/ScrollableSmall.importable.tsx b/dotcom-rendering/src/components/ScrollableSmall.importable.tsx index 912158e946b..6946c977304 100644 --- a/dotcom-rendering/src/components/ScrollableSmall.importable.tsx +++ b/dotcom-rendering/src/components/ScrollableSmall.importable.tsx @@ -104,7 +104,6 @@ export const ScrollableSmall = ({ showTopBarMobile={mobileBottomCards.includes(index)} canPlayInline={false} showLabsRedesign={showLabsRedesign} - fixImageWidth={true} /> ); From 41d4225c240c183a93872d7ac673993c9cd33ac9 Mon Sep 17 00:00:00 2001 From: Dominik Lander Date: Wed, 29 Oct 2025 11:29:47 +0000 Subject: [PATCH 3/4] Tablet podcast image should be 120px --- dotcom-rendering/src/components/Card/Card.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dotcom-rendering/src/components/Card/Card.tsx b/dotcom-rendering/src/components/Card/Card.tsx index 85ae6ece5ef..88a38678314 100644 --- a/dotcom-rendering/src/components/Card/Card.tsx +++ b/dotcom-rendering/src/components/Card/Card.tsx @@ -247,6 +247,10 @@ const podcastImageStyles = ( width: 98px; height: 98px; ${from.tablet} { + width: 120px; + height: 120px; + } + ${from.desktop} { width: ${isHorizontalOnDesktop ? 'unset' : '120px'}; height: ${isHorizontalOnDesktop ? 'unset' : '120px'}; } From 0c3dc4fa2245fcc4ceee163b35b6c69ff3380f8b Mon Sep 17 00:00:00 2001 From: Dominik Lander Date: Wed, 29 Oct 2025 11:52:31 +0000 Subject: [PATCH 4/4] Added comment. Put the flexBasis logic in MediaWrapper together --- dotcom-rendering/src/components/Card/Card.tsx | 1 + .../Card/components/MediaWrapper.tsx | 27 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/dotcom-rendering/src/components/Card/Card.tsx b/dotcom-rendering/src/components/Card/Card.tsx index 88a38678314..c2f8c888737 100644 --- a/dotcom-rendering/src/components/Card/Card.tsx +++ b/dotcom-rendering/src/components/Card/Card.tsx @@ -250,6 +250,7 @@ const podcastImageStyles = ( width: 120px; height: 120px; } + /** The image takes the full height on desktop, so that the waveform sticks to the bottom of the card. */ ${from.desktop} { width: ${isHorizontalOnDesktop ? 'unset' : '120px'}; height: ${isHorizontalOnDesktop ? 'unset' : '120px'}; diff --git a/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx b/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx index 8d8cbe5a981..23da3512c5d 100644 --- a/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx +++ b/dotcom-rendering/src/components/Card/components/MediaWrapper.tsx @@ -77,9 +77,13 @@ const mediaPaddingStyles = ( */ const flexBasisStyles = ({ mediaSize, + mediaType, + isSmallCard, isBetaContainer, }: { mediaSize: MediaSizeType; + mediaType: CardMediaType; + isSmallCard: boolean; isBetaContainer: boolean; }): SerializedStyles => { if (!isBetaContainer) { @@ -110,6 +114,15 @@ const flexBasisStyles = ({ } } + if (mediaType === 'podcast' && !isSmallCard) { + return css` + flex-basis: 120px; + ${from.desktop} { + flex-basis: 168px; + } + `; + } + switch (mediaSize) { default: case 'small': @@ -206,10 +219,13 @@ export const MediaWrapper = ({ (mediaType === 'slideshow' || mediaType === 'picture' || mediaType === 'youtube-video' || - mediaType === 'loop-video') && + mediaType === 'loop-video' || + mediaType === 'podcast') && isHorizontalOnDesktop && flexBasisStyles({ mediaSize, + mediaType, + isSmallCard, isBetaContainer, }), mediaType === 'avatar' && @@ -228,15 +244,6 @@ export const MediaWrapper = ({ mediaType !== 'podcast' && fixMobileMediaWidth(isBetaContainer, isSmallCard), isSmallCard && fixDesktopMediaWidth(), - mediaType === 'podcast' && - isHorizontalOnDesktop && - !isSmallCard && - css` - flex-basis: 120px; - ${from.desktop} { - flex-basis: 168px; - } - `, isHorizontalOnDesktop && css` ${from.tablet} {