Skip to content
Merged
31 changes: 31 additions & 0 deletions dotcom-rendering/.storybook/decorators/themeDecorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import type { CSSProperties } from 'react';
import type { ArticleFormat } from '../../src/lib/articleFormat';
import { storybookPaletteDeclarations as paletteDeclarations } from '../mocks/paletteDeclarations';
import { hostedPaletteOverrides } from '../../src/lib/hostedContentStyles';

const darkStoryCss = css`
background-color: ${sourcePalette.neutral[0]};
Expand Down Expand Up @@ -113,3 +114,33 @@ export const browserThemeDecorator =
</div>
</>
);

/**
* Colour scheme decorator specifically for hosted content pages,
* where the accent colour from the branding overrides some palette colours
*/
export const hostedPaletteDecorator =
(accentColour: string): Decorator =>
(Story, context) => (
<div
css={css`
${hostedPaletteOverrides('light', accentColour)}
${!!context.parameters?.config?.darkModeAvailable
? css`
@media (prefers-color-scheme: dark) {
${hostedPaletteOverrides('dark', accentColour)}
}
`
: ''}

[data-color-scheme='light'] & {
${hostedPaletteOverrides('light', accentColour)}
}
[data-color-scheme='dark'] & {
${hostedPaletteOverrides('dark', accentColour)}
}
`}
>
<Story />
</div>
);
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { hostedPaletteDecorator } from '../../.storybook/decorators/themeDecorator';
import preview from '../../.storybook/preview';
import { HostedContentDisclaimer } from './HostedContentDisclaimer';
import { Section } from './Section';

export default {
const meta = preview.meta({
component: HostedContentDisclaimer,
title: 'Components/HostedContentDisclaimer',
};

export const Default = () => {
return (
render: () => (
<Section
showSideBorders={false}
showTopBorder={false}
Expand All @@ -16,7 +15,8 @@ export const Default = () => {
>
<HostedContentDisclaimer />
</Section>
);
};
),
decorators: hostedPaletteDecorator('#d90c1f'),
});

Default.storyName = 'default';
export const Default = meta.story({});
38 changes: 20 additions & 18 deletions dotcom-rendering/src/components/HostedContentHeader.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import { palette as sourcePalette } from '@guardian/source/foundations';
import { hostedPaletteDecorator } from '../../.storybook/decorators/themeDecorator';
import preview from '../../.storybook/preview';
import type { Branding } from '../types/branding';
import { HostedContentHeader } from './HostedContentHeader.island';
import type { Props as HostedContentHeaderProps } from './HostedContentHeader.island';
import { Section } from './Section';

const branding = {
brandingType: { name: 'paid-content' },
sponsorName: 'We Are Still In',
logo: {
src: 'https://static.theguardian.com/commercial/sponsor/16/Aug/2018/d5e82ba3-297d-473d-8362-c04f519e5fe1-WASI-logo-grey.png',
dimensions: {
width: 1250,
height: 575,
},
link: 'https://www.wearestillin.com/',
label: 'Paid for by',
},
aboutThisLink:
'https://www.theguardian.com/info/2016/jan/25/content-funding',
hostedCampaignColour: '#d90c1f',
} satisfies Branding;

const meta = preview.meta({
component: HostedContentHeader,
title: 'Components/HostedContentHeader',
args: {
branding: {
brandingType: { name: 'paid-content' },
sponsorName: 'We Are Still In',
logo: {
src: 'https://static.theguardian.com/commercial/sponsor/16/Aug/2018/d5e82ba3-297d-473d-8362-c04f519e5fe1-WASI-logo-grey.png',
dimensions: {
width: 1250,
height: 575,
},
link: 'https://www.wearestillin.com/',
label: 'Paid for by',
},
aboutThisLink:
'https://www.theguardian.com/info/2016/jan/25/content-funding',
hostedCampaignColour: '#d90c1f',
} satisfies Branding,
},
args: { branding },
render: (args: HostedContentHeaderProps) => (
<Section
fullWidth={true}
Expand All @@ -39,6 +40,7 @@ const meta = preview.meta({
<HostedContentHeader {...args} />
</Section>
),
decorators: hostedPaletteDecorator(branding.hostedCampaignColour),
});

export const Default = meta.story();
35 changes: 13 additions & 22 deletions dotcom-rendering/src/components/HostedContentOnwards.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
import { hostedPaletteDecorator } from '../../.storybook/decorators/themeDecorator';
import preview from '../../.storybook/preview';
import { hostedOnwardsTrails } from '../../fixtures/manual/onwardsTrails';
import { HostedContentOnwards } from './HostedContentOnwards';

export default {
const meta = preview.meta({
component: HostedContentOnwards,
title: 'Components/HostedContentOnwards',
};
args: {
trails: hostedOnwardsTrails,
brandName: 'TrendAI',
},
render: (args) => <HostedContentOnwards {...args} />,
});

export const Default = () => {
return (
<HostedContentOnwards
trails={hostedOnwardsTrails}
brandName="TrendAI"
/>
);
};
export const Default = meta.story({});

Default.storyName = 'default';

export const WithAccentColour = () => {
return (
<HostedContentOnwards
trails={hostedOnwardsTrails}
brandName="TrendAI"
/>
);
};

WithAccentColour.storyName = 'with accent colour';
export const WithAccentColour = meta.story({
decorators: hostedPaletteDecorator('#d90c1f'),
});
11 changes: 10 additions & 1 deletion dotcom-rendering/src/components/HostedContentPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,18 @@ export const HostedContentPage = (props: WebProps | AppProps) => {
const { darkModeAvailable } = useConfig();
const format = { design, display, theme };

const { branding } =
frontendData.commercialProperties[frontendData.editionId];

return (
<StrictMode>
<Global styles={rootStyles(format, darkModeAvailable)} />
<Global
styles={rootStyles(
format,
darkModeAvailable,
branding?.hostedCampaignColour,

@dskamiotis dskamiotis Jul 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice 👍 moving the overrides to :root makes total sense — LightboxLayout lives outside <main> so it never could've picked these up before. Much cleaner to follow now.

)}
/>
{isWeb && <SkipTo id="maincontent" label="Skip to main content" />}
<Lightbox
format={format}
Expand Down
27 changes: 27 additions & 0 deletions dotcom-rendering/src/components/Lightbox.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { css } from '@emotion/react';
import { storage } from '@guardian/libs';
import { breakpoints } from '@guardian/source/foundations';
import type { Meta, StoryObj } from '@storybook/react-webpack5';
Expand Down Expand Up @@ -265,3 +266,29 @@ export const WithLabs = {
],
},
} satisfies Story;

export const WithHostedAccentColour = {
args: {
format: {
display: ArticleDisplay.Standard,
design: ArticleDesign.HostedGallery,
theme: ArticleSpecial.Labs,
},
images: [
{
...testImage,
title: 'Title',
displayCredit: true,
},
],
},
decorators: (Story) => (
<div
css={css`
--lightbox-divider: purple;
`}
>
{Story()}
</div>
),
} satisfies Story;
Loading
Loading