Skip to content

Commit ab3fbd2

Browse files
committed
rework the footer component to simplify rendering logic
1 parent 741483f commit ab3fbd2

2 files changed

Lines changed: 330 additions & 184 deletions

File tree

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

Lines changed: 39 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,17 @@ import {
77
space,
88
until,
99
} from '@guardian/source/foundations';
10-
import { Hide, Link, SvgCamera } from '@guardian/source/react-components';
10+
import { Hide } from '@guardian/source/react-components';
1111
import {
1212
ArticleDesign,
1313
type ArticleFormat,
1414
ArticleSpecial,
1515
} from '../../lib/articleFormat';
1616
import { isMediaCard } from '../../lib/cardHelpers';
17-
import { isWithinTwelveHours, secondsToDuration } from '../../lib/formatTime';
17+
import { secondsToDuration } from '../../lib/formatTime';
1818
import { appendLinkNameMedia } from '../../lib/getDataLinkName';
1919
import { getZIndex } from '../../lib/getZIndex';
2020
import { getOphanComponents } from '../../lib/labs';
21-
import { DISCUSSION_ID_DATA_ATTRIBUTE } from '../../lib/useCommentCount';
2221
import { BETA_CONTAINERS } from '../../model/enhanceCollections';
2322
import { palette } from '../../palette';
2423
import type { Branding } from '../../types/branding';
@@ -37,7 +36,6 @@ import type { MainMedia } from '../../types/mainMedia';
3736
import type { OnwardsSource } from '../../types/onwards';
3837
import { Avatar } from '../Avatar';
3938
import { BrandingLabel } from '../BrandingLabel';
40-
import { CardCommentCount } from '../CardCommentCount.importable';
4139
import { CardHeadline, type ResponsiveFontSize } from '../CardHeadline';
4240
import type { Loading } from '../CardPicture';
4341
import { CardPicture } from '../CardPicture';
@@ -57,8 +55,7 @@ import { SupportingKeyStoriesContent } from '../SupportingKeyStoriesContent';
5755
import { SvgMediaControlsPlay } from '../SvgMediaControlsPlay';
5856
import { YoutubeBlockComponent } from '../YoutubeBlockComponent.importable';
5957
import { AvatarContainer } from './components/AvatarContainer';
60-
import { CardAge } from './components/CardAge';
61-
import { CardFooter } from './components/CardFooter';
58+
import { CardFooter } from './components/CardFooterNew';
6259
import {
6360
CardLayout,
6461
decideAvatarPosition,
@@ -358,14 +355,6 @@ const decideSublinkPosition = (
358355
return alignment === 'vertical' ? 'inner' : 'outer';
359356
};
360357

361-
const liveBulletStyles = css`
362-
width: 9px;
363-
height: 9px;
364-
border-radius: 50%;
365-
background-color: ${palette('--pill-bullet')};
366-
margin-right: ${space[1]}px;
367-
`;
368-
369358
export const Card = ({
370359
linkTo,
371360
format,
@@ -453,143 +442,6 @@ export const Card = ({
453442
*/
454443
const isVideoArticle = format.design === ArticleDesign.Video;
455444

456-
const isLabs = format.theme === ArticleSpecial.Labs;
457-
458-
const decideAge = () => {
459-
if (!webPublicationDate) return undefined;
460-
const withinTwelveHours = isWithinTwelveHours(webPublicationDate);
461-
462-
const shouldShowAge =
463-
isStorylines ||
464-
isTagPage ||
465-
!!onwardsSource ||
466-
(showAge && withinTwelveHours);
467-
468-
if (!shouldShowAge) return undefined;
469-
470-
return (
471-
<CardAge
472-
webPublication={{
473-
date: webPublicationDate,
474-
isWithinTwelveHours: withinTwelveHours,
475-
}}
476-
showClock={showClock}
477-
serverTime={serverTime}
478-
isTagPage={isTagPage}
479-
/>
480-
);
481-
};
482-
483-
const CommentCount = () =>
484-
!!discussionId && (
485-
<Link
486-
{...{
487-
[DISCUSSION_ID_DATA_ATTRIBUTE]: discussionId,
488-
}}
489-
data-ignore="global-link-styling"
490-
data-link-name="Comment count"
491-
href={`${linkTo}#comments`}
492-
cssOverrides={css`
493-
/* See: https://css-tricks.com/nested-links/ */
494-
z-index: ${getZIndex('card-nested-link')};
495-
/* The following styles turn off those provided by Link */
496-
color: inherit;
497-
/* stylelint-disable-next-line property-disallowed-list */
498-
font-family: inherit;
499-
font-size: inherit;
500-
line-height: inherit;
501-
text-decoration: none;
502-
min-height: 10px;
503-
`}
504-
>
505-
<Island priority="feature" defer={{ until: 'visible' }}>
506-
<CardCommentCount
507-
discussionApiUrl={discussionApiUrl}
508-
discussionId={discussionId}
509-
/>
510-
</Island>
511-
</Link>
512-
);
513-
514-
const MediaOrNewsletterPill = () => (
515-
<div
516-
css={css`
517-
margin-top: auto;
518-
display: flex;
519-
${isStorylines &&
520-
`
521-
flex-direction: column;
522-
gap: ${space[1]}px;
523-
align-items: flex-start;
524-
`}
525-
`}
526-
>
527-
{/* Usually, we either display the pill or the footer,
528-
but if the card appears in the storylines section on tag pages
529-
then we do want to display the date on these cards as well as the media pill.
530-
*/}
531-
{isStorylines && (
532-
<CardFooter
533-
format={format}
534-
age={decideAge()}
535-
commentCount={<CommentCount />}
536-
cardBranding={
537-
isOnwardContent ? <LabsBranding /> : undefined
538-
}
539-
showLivePlayable={showLivePlayable}
540-
/>
541-
)}
542-
543-
{mainMedia?.type === 'YoutubeVideo' && isVideoArticle && (
544-
<>
545-
{mainMedia.duration === 0 ? (
546-
<Pill
547-
content="Live"
548-
icon={<div css={liveBulletStyles} />}
549-
/>
550-
) : (
551-
<Pill
552-
content={secondsToDuration(mainMedia.duration)}
553-
icon={<SvgMediaControlsPlay width={18} />}
554-
prefix="Video"
555-
/>
556-
)}
557-
</>
558-
)}
559-
{mainMedia?.type === 'Audio' && (
560-
<Pill
561-
content={mainMedia.duration}
562-
icon={<SvgMediaControlsPlay width={18} />}
563-
prefix="Podcast"
564-
/>
565-
)}
566-
{mainMedia?.type === 'Gallery' && (
567-
<Pill
568-
content={mainMedia.count}
569-
icon={<SvgCamera />}
570-
prefix="Gallery"
571-
/>
572-
)}
573-
{mainMedia?.type === 'SelfHostedVideo' &&
574-
(format.design === ArticleDesign.Video ? (
575-
<Pill
576-
content=""
577-
icon={<SvgMediaControlsPlay width={18} />}
578-
prefix="Video"
579-
/>
580-
) : format.design === ArticleDesign.Audio ? (
581-
<Pill
582-
content=""
583-
icon={<SvgMediaControlsPlay width={18} />}
584-
prefix="Podcast"
585-
/>
586-
) : format.design === ArticleDesign.Gallery ? (
587-
<Pill content="" icon={<SvgCamera />} prefix="Gallery" />
588-
) : null)}
589-
{isNewsletter && <Pill content="Newsletter" />}
590-
</div>
591-
);
592-
593445
if (snapData?.embedHtml) {
594446
return (
595447
<SnapCssSandbox snapData={snapData}>
@@ -900,7 +752,7 @@ export const Card = ({
900752
alignment="end"
901753
ophanComponentLink={dataAttributes?.ophanComponentLink}
902754
ophanComponentName={dataAttributes?.ophanComponentName}
903-
isLabs={isLabs}
755+
isLabs={format.theme === ArticleSpecial.Labs}
904756
dataTestId="card-branding-logo"
905757
/>
906758
</div>
@@ -922,7 +774,7 @@ export const Card = ({
922774
alignment="end"
923775
ophanComponentLink={dataAttributes?.ophanComponentLink}
924776
ophanComponentName={dataAttributes?.ophanComponentName}
925-
isLabs={isLabs}
777+
isLabs={format.theme === ArticleSpecial.Labs}
926778
/>
927779
</div>
928780
</>
@@ -1340,33 +1192,28 @@ export const Card = ({
13401192
/>
13411193
)}
13421194

1195+
{/** Footer rendered inside the card boundary */}
13431196
{!isOpinionCardWithAvatar && (
1344-
<>
1345-
{showPill ? (
1346-
<>
1347-
{!!branding &&
1348-
format.theme ===
1349-
ArticleSpecial.Labs &&
1350-
isOnwardContent && (
1351-
<LabsBranding />
1352-
)}
1353-
<MediaOrNewsletterPill />
1354-
</>
1355-
) : (
1356-
<CardFooter
1357-
format={format}
1358-
age={decideAge()}
1359-
commentCount={<CommentCount />}
1360-
cardBranding={
1361-
isOnwardContent ? (
1362-
<LabsBranding />
1363-
) : undefined
1364-
}
1365-
showLivePlayable={showLivePlayable}
1366-
/>
1367-
)}
1368-
</>
1197+
<CardFooter
1198+
format={format}
1199+
showLivePlayable={showLivePlayable}
1200+
showAge={showAge}
1201+
cardBranding={<LabsBranding />}
1202+
mainMedia={mainMedia}
1203+
isNewsletter={isNewsletter}
1204+
showPill={showPill}
1205+
isStorylines={isStorylines}
1206+
onwardsSource={onwardsSource}
1207+
webPublicationDate={webPublicationDate}
1208+
showClock={showClock}
1209+
serverTime={serverTime}
1210+
isTagPage={isTagPage}
1211+
discussionId={discussionId}
1212+
discussionApiUrl={discussionApiUrl}
1213+
linkTo={linkTo}
1214+
/>
13691215
)}
1216+
13701217
{showLivePlayable &&
13711218
liveUpdatesPosition === 'inner' && (
13721219
<Island
@@ -1453,20 +1300,28 @@ export const Card = ({
14531300
{isOpinionCardWithAvatar && (
14541301
<CardFooter
14551302
format={format}
1456-
age={decideAge()}
1457-
commentCount={<CommentCount />}
14581303
showLivePlayable={showLivePlayable}
1304+
showAge={showAge}
1305+
cardBranding={<LabsBranding />}
1306+
mainMedia={mainMedia}
1307+
isNewsletter={isNewsletter}
14591308
shouldReserveSpace={{
14601309
mobile: avatarPosition.mobile === 'bottom',
14611310
desktop: avatarPosition.desktop === 'bottom',
14621311
}}
1312+
showPill={showPill}
1313+
isStorylines={isStorylines}
1314+
onwardsSource={onwardsSource}
1315+
webPublicationDate={webPublicationDate}
1316+
showClock={showClock}
1317+
serverTime={serverTime}
1318+
isTagPage={isTagPage}
1319+
discussionId={discussionId}
1320+
discussionApiUrl={discussionApiUrl}
1321+
linkTo={linkTo}
14631322
/>
14641323
)}
14651324
</div>
1466-
1467-
{!isOnwardContent && format.theme === ArticleSpecial.Labs && (
1468-
<LabsBranding />
1469-
)}
14701325
</CardWrapper>
14711326
);
14721327
};

0 commit comments

Comments
 (0)