Skip to content

Use CallToActionAtomBlockElement in Hosted Content#15521

Open
deedeeh wants to merge 6 commits intomainfrom
dina/use-call-to-action-block-element
Open

Use CallToActionAtomBlockElement in Hosted Content#15521
deedeeh wants to merge 6 commits intomainfrom
dina/use-call-to-action-block-element

Conversation

@deedeeh
Copy link
Contributor

@deedeeh deedeeh commented Mar 12, 2026

What does this change?

This PR is to use the CallToActionAtomBlockElement in Hosted Content and consume the data which should be the last piece of the puzzle to migrate the CTA atom to DCAR which is only used by the Hosted Content.

Related PRs guardian/frontend#28653 and #15483

The changes include:

  • Rendering the CTA data
  • Followed the new designs for the CTA so lots of CSS
  • Updated the story with the correct properties name
  • Added the new CallToActionAtomBlockElement data to the hostedArticle.ts and hostedVideo.ts manual fixtures so it could be rendered in storybook.
  • Added unit tests

The next step in the CTA work is to use the accentColour for the CTA button in light mode and a neutral colour in dark mode but it's better to do it in a separate PR.

Why?

This is part of the Hosted Content migration to DCAR.

Screenshots

I added screenshots with label but we can also have CTA without label, which is the heading.

Before After
before after
before2 after2
before3 after3
before4 after4
before5 after5

@deedeeh deedeeh changed the title Dina/use call to action block element Use CallToActionAtomBlockElement in Hosted Content Mar 12, 2026
@github-actions
Copy link

github-actions bot commented Mar 12, 2026

@deedeeh deedeeh added the maintenance Departmental tracking: maintenance work, not a fix or a feature label Mar 12, 2026
@deedeeh deedeeh force-pushed the dina/use-call-to-action-block-element branch from 617f238 to b3358f4 Compare March 12, 2026 13:23
@deedeeh deedeeh force-pushed the dina/use-call-to-action-block-element branch from b3358f4 to 79a77e9 Compare March 12, 2026 14:24
@deedeeh deedeeh marked this pull request as ready for review March 12, 2026 14:26
@github-actions
Copy link

Hello 👋! When you're ready to run Chromatic, please apply the run_chromatic label to this PR.

You will need to reapply the label each time you want to run Chromatic.

Click here to see the Chromatic project.

url: string;
image?: string;
label?: string;
btnText?: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think buttonText is easier to read personally, and in general feel that the previous prop names were more intuitive. We don't need them to match the underlying data

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I did add the previous prop names back. I do agree with you they are clearer. Done 369581a

Comment on lines +25 to +117
const overlayMaskGradientStyles = (
angle: string,
startPosition: number,
) => {
const positions = [0, 8, 16, 24, 32, 40, 48, 56, 64].map(
(offset) => startPosition + offset,
);
return css`
mask-image: linear-gradient(
${angle},
transparent ${positions[0]}px,
rgba(0, 0, 0, 0.0381) ${positions[1]}px,
rgba(0, 0, 0, 0.1464) ${positions[2]}px,
rgba(0, 0, 0, 0.3087) ${positions[3]}px,
rgba(0, 0, 0, 0.5) ${positions[4]}px,
rgba(0, 0, 0, 0.6913) ${positions[5]}px,
rgba(0, 0, 0, 0.8536) ${positions[6]}px,
rgba(0, 0, 0, 0.9619) ${positions[7]}px,
rgb(0, 0, 0) ${positions[8]}px
);
`;
};

const blurStyles = css`
position: absolute;
inset: 0;
backdrop-filter: blur(12px) brightness(0.5);
@supports not (backdrop-filter: blur(12px)) {
background-color: ${transparentColour(
sourcePalette.neutral[10],
0.7,
)};
}
${overlayMaskGradientStyles('180deg', 0)};

${from.mobileLandscape} {
${overlayMaskGradientStyles('180deg', 20)};
}

${from.tablet} {
${overlayMaskGradientStyles('180deg', 80)};
}

${from.desktop} {
${overlayMaskGradientStyles('180deg', 100)};
}

${from.leftCol} {
${overlayMaskGradientStyles('180deg', 210)};
}
`;

const buttonWrapperStyles = css`
${blurStyles}
display: flex;
position: absolute;
flex-direction: column;
justify-content: end;
align-items: center;
padding: 0 ${space[2]}px ${space[6]}px;
bottom: 0;
left: 0;
right: 0;

${from.tablet} {
flex-direction: row;
align-items: flex-end;
padding: ${space[8]}px ${space[9]}px;
}

${from.desktop} {
justify-content: start;
padding: ${space[8]}px ${space[5]}px;
}
`;

const labelStyles = css`
${textSansBold28}
width: 100%;
margin-bottom: ${space[5]}px;
color: white;

${from.tablet} {
${textSansBold34}
margin: 0;
padding-right: ${space[8]}px;
}

${from.desktop} {
width: auto;
max-width: 621px;
}
`;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move the styles out of the component itself? It's not the usual pattern in DCR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That wasn't meant to happen. Done 369581a

color: white;

${from.tablet} {
${textSansBold34}
Copy link
Contributor

Choose a reason for hiding this comment

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

As far as I can see, the designs say text sans bold 24 until tablet then text sans bold 28 from there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was looking at a different Figma file and not the latest that was sent to the Hosted Content P&E update chat. Done 369581a

Comment on lines +159 to +165
cssOverrides={css`
width: 100%;

${from.tablet} {
width: auto;
}
`}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally we wouldn't use cssOverrides. I know the prop exists but there was some discussion a while ago about removing it in favour of more standard control of button styling in the design system.
Can we apply these using general styles focussed towards this button? Perhaps in the buttonWrapper css?

css`
  ...
  button {
    width: 100%;
    ${from.tablet} {
	  width: auto;
	}
  }
`


${from.desktop} {
width: auto;
max-width: 621px;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why 621px? This seems oddly specific!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I specified that based on the initial Figma file as that's the max-width for the text. When I looked in the latest Figma I can see different values as the following:

Image Image Image

I think I need to add a max-width for the text.

${from.tablet} {
${textSansBold34}
margin: 0;
padding-right: ${space[8]}px;
Copy link
Contributor

Choose a reason for hiding this comment

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

That's a large value for padding-right. If this is to restrict the width of the text area, we could use something like a calculation instead to make it more explicit what this is for?

max-width: calc(100% - ${buttonWidth}px - ${buttonPadding}px);

Or could make the parent a flex container and specify a flex-basis for both the button and the text

wrapper {
  display: flex;
}
label {
  flex-basis: 75%;
}
button {
  flex-basis: 25%;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why can't we just use a padding-right? The design specifically got 20px between the text and the button for all breakpoints from tablet.

Image

${textSansBold28}
width: 100%;
margin-bottom: ${space[5]}px;
color: white;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use a palette colour here so we remember to change it later with theming?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup can do that. Done 369581a

${from.tablet} {
flex-direction: row;
align-items: flex-end;
padding: ${space[8]}px ${space[9]}px;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an unusually large amount of padding - is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well that's what I saw in the initial Figma file and also I just checked the latest Figma that you are referring to and there is a 32px top and bottom and 34px right and left but instead I used 36px to be able to use Source as we don't have 34px when we use space.

Image

'model.dotcomrendering.pageElements.CallToActionAtomBlockElement',
);

//We need to remove the CTA block element from the blocks that are rendered in the article body, otherwise it will be rendered twice.
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 good explanation of why we're doing something funny here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance Departmental tracking: maintenance work, not a fix or a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants