Skip to content

Commit

Permalink
Merge branch 'main' into skb/update-not-thrasher-copy-colour
Browse files Browse the repository at this point in the history
  • Loading branch information
sookburt authored Dec 12, 2024
2 parents 4fed7ac + f4a35f7 commit 099cb29
Show file tree
Hide file tree
Showing 30 changed files with 1,129 additions and 486 deletions.
6 changes: 3 additions & 3 deletions apps-rendering/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-react": "7.33.2",
"express": "4.21.0",
"html-webpack-plugin": "5.6.0",
"html-webpack-plugin": "5.6.3",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jsdom": "16.7.0",
Expand All @@ -103,9 +103,9 @@
"tslib": "2.6.2",
"tsx": "4.6.2",
"typescript": "5.5.3",
"webpack": "5.94.0",
"webpack": "5.97.1",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4",
"webpack-dev-server": "5.1.0",
"webpack-manifest-plugin": "5.0.0",
"whatwg-fetch": "3.6.19",
"winston": "3.11.0",
Expand Down
4 changes: 2 additions & 2 deletions dotcom-rendering/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@
"unified": "11.0.5",
"valibot": "0.28.1",
"web-vitals": "4.2.3",
"webpack": "5.94.0",
"webpack": "5.97.1",
"webpack-assets-manifest": "5.2.1",
"webpack-bundle-analyzer": "4.10.2",
"webpack-cli": "5.1.4",
"webpack-dev-middleware": "7.4.2",
"webpack-dev-server": "5.0.4",
"webpack-dev-server": "5.1.0",
"webpack-hot-middleware": "2.26.1",
"webpack-hot-server-middleware": "0.6.1",
"webpack-manifest-plugin": "5.0.0",
Expand Down
211 changes: 211 additions & 0 deletions dotcom-rendering/src/components/BigSixOnwardsContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import { css } from '@emotion/react';
import { from, headlineBold24, space } from '@guardian/source/foundations';
import { decideFormat } from '../lib/articleFormat';
import { useApi } from '../lib/useApi';
import { palette } from '../palette';
import type { DCRFrontCard } from '../types/front';
import type { FETrailType } from '../types/trails';
import { Card } from './Card/Card';
import { LI } from './Card/components/LI';
import { UL } from './Card/components/UL';
import { LeftColumn } from './LeftColumn';
import { Placeholder } from './Placeholder';

type OnwardsResponse = {
trails: FETrailType[];
heading: string;
displayname: string;
description: string;
};

const containerStyles = css`
display: flex;
flex-direction: column;
padding-bottom: ${space[6]}px;
${from.leftCol} {
flex-direction: row;
padding-right: 80px;
}
`;

const headerStyles = css`
${headlineBold24};
color: ${palette('--carousel-text')};
padding-bottom: ${space[2]}px;
padding-top: ${space[1]}px;
margin-left: 0;
`;
const mobileHeaderStyles = css`
${headerStyles};
${from.tablet} {
padding-left: 10px;
}
${from.leftCol} {
display: none;
}
`;

const convertFETrailToDcrTrail = (
trails: FETrailType[],
discussionApiUrl: string,
): DCRFrontCard[] =>
trails.map((trail) => ({
dataLinkName: 'onwards-content-card',
discussionId: trail.discussion?.discussionId,
discussionApiUrl,
format: decideFormat(trail.format),
headline: trail.headline,
image: {
src: trail.masterImage ?? '',
altText: trail.linkText ?? '',
},
isExternalLink: false,
onwardsSource: 'related-content',
showLivePlayable: false,
showQuotedHeadline: false,
url: trail.url,
webPublicationDate: trail.webPublicationDate,
}));

type Props = { url: string; discussionApiUrl: string };

/**
* Big Six refers to the style of the onwards content container. It displays six article
* cards in a gallery-style container, as opposed to a carousel.
*/
export const BigSixOnwardsContent = ({ url, discussionApiUrl }: Props) => {
const { data, error } = useApi<OnwardsResponse>(url);

if (error) {
// Send the error to Sentry and then prevent the element from rendering
window.guardian.modules.sentry.reportError(error, 'onwards-lower');
return null;
}

if (!data?.trails) {
return (
<Placeholder
height={580} // best guess at typical height
shouldShimmer={false}
backgroundColor={palette('--article-background')}
/>
);
}

const trails: DCRFrontCard[] = convertFETrailToDcrTrail(
data.trails,
discussionApiUrl,
);

const firstSlice75 = trails.slice(0, 1);
const firstSlice25 = trails.slice(1, 2);
const secondSlice25 = trails.slice(2, 6);

const heading = data.heading || data.displayname;

return (
<div
data-component="onwards-content-gallery-style"
css={containerStyles}
>
<LeftColumn>
<h2 css={headerStyles}>
<span>{heading}</span>
</h2>
</LeftColumn>
<h2 css={mobileHeaderStyles}>
<span>{heading}</span>
</h2>
<div>
<UL direction="row" padBottom={true}>
{firstSlice75.map((trail) => (
<LI key={trail.url} padSides={true} percentage="75%">
<Card
absoluteServerTimes={false}
imagePositionOnDesktop="right"
imagePositionOnMobile="top"
imageSize="large"
imageLoading="lazy"
linkTo={trail.url}
format={trail.format}
headlineText={trail.headline}
image={trail.image}
dataLinkName={`onwards-content-gallery-style ${trail.dataLinkName}-position-0`}
discussionId={trail.discussionId}
discussionApiUrl={trail.discussionApiUrl}
isExternalLink={trail.isExternalLink}
showAge={true}
webPublicationDate={trail.webPublicationDate}
onwardsSource="related-content"
/>
</LI>
))}
{firstSlice25.map((trail) => (
<LI
key={trail.url}
padSides={true}
showDivider={true}
percentage="25%"
>
<Card
absoluteServerTimes={false}
imagePositionOnDesktop="top"
imagePositionOnMobile="left"
imageSize="small"
imageLoading="lazy"
linkTo={trail.url}
format={trail.format}
headlineText={trail.headline}
image={trail.image}
dataLinkName={`onwards-content-gallery-style ${trail.dataLinkName}-position-1`}
discussionId={trail.discussionId}
discussionApiUrl={trail.discussionApiUrl}
isExternalLink={trail.isExternalLink}
showAge={true}
webPublicationDate={trail.webPublicationDate}
onwardsSource="related-content"
/>
</LI>
))}
</UL>
<UL direction="row">
{secondSlice25.map((trail, index) => {
const dataLinkName = `onwards-content-gallery-style ${
trail.dataLinkName
}-position-${index + 2}`;

return (
<LI
key={trail.url}
padSides={true}
showDivider={index > 0}
>
<Card
absoluteServerTimes={false}
imagePositionOnDesktop="top"
imagePositionOnMobile="left"
imageSize="small"
imageLoading="lazy"
linkTo={trail.url}
format={trail.format}
headlineText={trail.headline}
image={trail.image}
dataLinkName={dataLinkName}
discussionId={trail.discussionId}
discussionApiUrl={trail.discussionApiUrl}
isExternalLink={trail.isExternalLink}
showAge={true}
webPublicationDate={
trail.webPublicationDate
}
onwardsSource="related-content"
/>
</LI>
);
})}
</UL>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import {
} from '@guardian/source/foundations';
import { Button } from '@guardian/source/react-components';
import { useEffect, useState } from 'react';
import type { ArticleFormat } from '../lib/articleFormat';
import { decidePalette } from '../lib/decidePalette';
import { palette } from '../palette';
import MinusIcon from '../static/icons/minus.svg';
import PlusIcon from '../static/icons/plus.svg';
import type {
CalloutBlockElement,
CalloutBlockElementV2,
} from '../types/content';
import type { Palette } from '../types/palette';
import { Form } from './CalloutEmbed/Form';

const wrapperStyles = css`
Expand Down Expand Up @@ -79,10 +77,10 @@ const summaryContentWrapper = css`
flex-direction: row;
`;

const speechBubbleStyles = (palette: Palette) => css`
const speechBubbleStyles = css`
${textSansBold17}
color: ${srcPalette.neutral[100]};
background-color: ${palette.background.speechBubble};
background-color: ${palette('--speech-bubble-background')};
min-width: 88px;
padding-bottom: 6px;
padding-left: 10px;
Expand All @@ -93,7 +91,7 @@ const speechBubbleStyles = (palette: Palette) => css`
height: 22px;
border-bottom-right-radius: 18px;
position: absolute;
background-color: ${palette.background.speechBubble};
background-color: ${palette('--speech-bubble-background')};
}
`;

Expand Down Expand Up @@ -147,10 +145,8 @@ type FormDataType = { [key in string]: unknown };
*/
export const CalloutEmbedBlockComponent = ({
callout,
format,
}: {
callout: CalloutBlockElement | CalloutBlockElementV2;
format: ArticleFormat;
}) => {
let expandFormButtonRef: HTMLButtonElement | null = null;
let firstFieldElementRef: HTMLElement | null = null;
Expand All @@ -160,8 +156,6 @@ export const CalloutEmbedBlockComponent = ({
const [error, setError] = useState('');
const [submissionSuccess, setSubmissionSuccess] = useState(false);

const palette = decidePalette(format);

const { title, description, formFields } = callout;

const onSubmit = async (formData: FormDataType) => {
Expand Down Expand Up @@ -312,7 +306,7 @@ export const CalloutEmbedBlockComponent = ({
<summary css={summaryStyles}>
<div css={summaryContentWrapper}>
<div css={speechBubbleWrapperStyles}>
<div css={speechBubbleStyles(palette)}>
<div css={speechBubbleStyles}>
<h4>Share your story</h4>
</div>
</div>
Expand All @@ -338,7 +332,7 @@ export const CalloutEmbedBlockComponent = ({
<summary css={summaryStyles}>
<div css={summaryContentWrapper}>
<div css={speechBubbleWrapperStyles}>
<div css={speechBubbleStyles(palette)}>
<div css={speechBubbleStyles}>
<h4>Share your story</h4>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Decorator, Meta, StoryObj } from '@storybook/react';
import { centreColumnDecorator } from '../../.storybook/decorators/gridDecorators';
import { allModes } from '../../.storybook/modes';
import { calloutCampaign } from '../../fixtures/manual/calloutCampaign';
import { ArticleDesign, ArticleDisplay, Pillar } from '../lib/articleFormat';
import { customMockFetch } from '../lib/mockRESTCalls';
import { CalloutEmbedBlockComponent as CalloutEmbedBlock } from './CalloutEmbedBlockComponent.importable';

Expand Down Expand Up @@ -39,11 +38,6 @@ const goodRequest: Decorator<Story['args']> = (Story) => {
export const CalloutEmbedBlockComponent = {
args: {
callout: calloutCampaign,
format: {
display: ArticleDisplay.Standard,
design: ArticleDesign.Standard,
theme: Pillar.News,
},
},
decorators: [goodRequest],
} satisfies Story;
2 changes: 2 additions & 0 deletions dotcom-rendering/src/components/Carousel.importable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ const Title = ({
<span css={titleStyle(isCuratedContent)}>{title}</span>
</h2>
);

type CarouselCardProps = {
isFirst: boolean;
index: number;
Expand Down Expand Up @@ -500,6 +501,7 @@ const CarouselCard = ({
}: CarouselCardProps) => {
const isVideoContainer = containerType === 'fixed/video';
const cardImagePosition = isOnwardContent ? 'bottom' : 'top';

return (
<LI
percentage="25%"
Expand Down
Loading

0 comments on commit 099cb29

Please sign in to comment.