From d8595db8a212ed4395663413085104436a01fda0 Mon Sep 17 00:00:00 2001 From: Max Duval Date: Wed, 8 Nov 2023 10:32:11 +0000 Subject: [PATCH] feat(ContainerOverrides): helper for palette this enables overriding specific palette values in a container, if there is a special container palette applied to it. It demonstrates usage with `--headline-colour` usage in CardHeadline, which is overridden instead of having the three following values: - text.headline - text.cardHeadline - text.dynamoHeadline --- dotcom-rendering/index.d.ts | 7 + .../Card/components/CardWrapper.tsx | 21 +- .../src/components/CardHeadline.stories.tsx | 233 ++++++++---------- .../src/components/CardHeadline.tsx | 5 +- .../src/components/ContainerOverrides.tsx | 49 ++++ 5 files changed, 181 insertions(+), 134 deletions(-) create mode 100644 dotcom-rendering/src/components/ContainerOverrides.tsx diff --git a/dotcom-rendering/index.d.ts b/dotcom-rendering/index.d.ts index 1a1c58d2719..b066dd816ef 100644 --- a/dotcom-rendering/index.d.ts +++ b/dotcom-rendering/index.d.ts @@ -551,3 +551,10 @@ declare namespace JSX { 'data-link-name'?: string; } } + +declare namespace React { + interface CSSProperties { + // Allow custom properties to be passed to the style prop + [key: `--${string}`]: string | undefined; + } +} diff --git a/dotcom-rendering/src/components/Card/components/CardWrapper.tsx b/dotcom-rendering/src/components/Card/components/CardWrapper.tsx index b46714fa96f..d07bf4d4441 100644 --- a/dotcom-rendering/src/components/Card/components/CardWrapper.tsx +++ b/dotcom-rendering/src/components/Card/components/CardWrapper.tsx @@ -5,6 +5,7 @@ import { from, neutral } from '@guardian/source-foundations'; import { decidePalette } from '../../../lib/decidePalette'; import type { DCRContainerPalette } from '../../../types/front'; import type { Palette } from '../../../types/palette'; +import { ContainerOverrides } from '../../ContainerOverrides'; import { FormatBoundary } from '../../FormatBoundary'; type Props = { @@ -182,14 +183,20 @@ export const CardWrapper = ({ const palette = decidePalette(format, containerPalette); return ( -
- {children} -
+
+ {children} +
+
); }; diff --git a/dotcom-rendering/src/components/CardHeadline.stories.tsx b/dotcom-rendering/src/components/CardHeadline.stories.tsx index 1e328d91eb1..c835faf5084 100644 --- a/dotcom-rendering/src/components/CardHeadline.stories.tsx +++ b/dotcom-rendering/src/components/CardHeadline.stories.tsx @@ -1,14 +1,16 @@ +import type { ArticleFormat } from '@guardian/libs'; import { ArticleDesign, ArticleDisplay, ArticleSpecial, Pillar, } from '@guardian/libs'; -import { breakpoints, specialReport } from '@guardian/source-foundations'; +import { breakpoints, palette } from '@guardian/source-foundations'; import type { StoryObj } from '@storybook/react'; import { splitTheme } from '../../.storybook/decorators/splitThemeDecorator'; import type { DCRContainerPalette } from '../types/front'; import { CardHeadline } from './CardHeadline'; +import { ContainerOverrides } from './ContainerOverrides'; import { Section } from './Section'; export default { @@ -39,6 +41,11 @@ export const Article = () => ( ); Article.storyName = 'Article'; +const specialReport = { + display: ArticleDisplay.Standard, + design: ArticleDesign.Analysis, + theme: ArticleSpecial.SpecialReport, +} satisfies ArticleFormat; export const Analysis = () => ( <> {smallHeadlineSizes.map((size) => ( @@ -110,16 +117,14 @@ export const Analysis = () => ( fullWidth={true} showTopBorder={false} showSideBorders={false} - backgroundColour={specialReport[300]} + backgroundColour={palette.specialReport[300]} > - + + + ); @@ -305,26 +310,35 @@ export const OpinionKicker = () => ( ); OpinionKicker.storyName = 'With an opinion kicker'; -export const SpecialReport = () => ( +export const SpecialReport: StoryObj = ({ + format, +}: { + format: ArticleFormat; +}) => (
- + + +
); SpecialReport.storyName = 'With theme SpecialReport'; +SpecialReport.args = { + format: { + display: ArticleDisplay.Standard, + design: ArticleDesign.Standard, + theme: ArticleSpecial.SpecialReport, + }, +}; export const Busy = () => (
@@ -342,105 +356,70 @@ export const Busy = () => ( ); Busy.storyName = 'Lifestyle opinion'; -export const Byline = () => ( - <> -
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
+export const Byline: StoryObj = ({ format }: { format: ArticleFormat }) => ( +
+ -
- + +
); Byline.storyName = 'With byline'; +Byline.decorators = [ + splitTheme([ + { + display: ArticleDisplay.Standard, + design: ArticleDesign.Feature, + theme: ArticleSpecial.Labs, + }, + { + display: ArticleDisplay.Standard, + design: ArticleDesign.Feature, + theme: Pillar.News, + }, + { + display: ArticleDisplay.Standard, + design: ArticleDesign.Feature, + theme: Pillar.Sport, + }, + { + display: ArticleDisplay.Standard, + design: ArticleDesign.Feature, + theme: Pillar.Culture, + }, + { + display: ArticleDisplay.Standard, + design: ArticleDesign.Feature, + theme: Pillar.Lifestyle, + }, + { + display: ArticleDisplay.Standard, + design: ArticleDesign.Feature, + theme: Pillar.Opinion, + }, + { + display: ArticleDisplay.Standard, + design: ArticleDesign.Feature, + theme: ArticleSpecial.SpecialReport, + }, + ]), +]; const containerPalettes = [ 'EventPalette', @@ -469,17 +448,23 @@ export const WithContainerOverrides: StoryObj = ({ showSideBorders={false} containerPalette={containerPalette} > - + containerPalette={containerPalette} + isDynamo={false} + > + +
))} diff --git a/dotcom-rendering/src/components/CardHeadline.tsx b/dotcom-rendering/src/components/CardHeadline.tsx index 25b706d0d38..d26d6706dde 100644 --- a/dotcom-rendering/src/components/CardHeadline.tsx +++ b/dotcom-rendering/src/components/CardHeadline.tsx @@ -14,6 +14,7 @@ import { Link, SvgExternal } from '@guardian/source-react-components'; import React from 'react'; import { decidePalette } from '../lib/decidePalette'; import { getZIndex } from '../lib/getZIndex'; +import { palette as schemedPalette } from '../palette'; import type { DCRContainerPalette } from '../types/front'; import type { Palette } from '../types/palette'; import { Byline } from './Byline'; @@ -287,9 +288,7 @@ export const CardHeadline = ({ {showQuotes && } diff --git a/dotcom-rendering/src/components/ContainerOverrides.tsx b/dotcom-rendering/src/components/ContainerOverrides.tsx new file mode 100644 index 00000000000..db59eace65e --- /dev/null +++ b/dotcom-rendering/src/components/ContainerOverrides.tsx @@ -0,0 +1,49 @@ +import { css } from '@emotion/react'; +import { decideContainerOverrides } from '../lib/decideContainerOverrides'; +import { decidePalette } from '../lib/decidePalette'; +import type { palette } from '../palette'; +import type { DCRContainerPalette } from '../types/front'; + +type Props = { + children: React.ReactNode; + format: ArticleFormat; + isDynamo: boolean; + containerPalette?: DCRContainerPalette; +}; + +/** @see https://developer.mozilla.org/en-US/docs/Web/CSS/display-box#contents */ +const displayContents = css` + display: contents; +`; + +type ColourName = Parameters[0]; + +/** + * Add CSS custom property overrides for palette colours in a given container + */ +export const ContainerOverrides = ({ + containerPalette, + isDynamo, + children, + format, +}: Props) => { + const { text } = containerPalette + ? decideContainerOverrides(containerPalette) + : { text: undefined }; + + const paletteOverrides = { + '--headline-colour': isDynamo + ? text?.dynamoHeadline ?? decidePalette(format).text.dynamoHeadline + : text?.cardHeadline ?? decidePalette(format).text.cardHeadline, + } satisfies Partial>; + + return ( +
+ {children} +
+ ); +};