diff --git a/dotcom-rendering/src/components/AffiliateDisclaimer.importable.tsx b/dotcom-rendering/src/components/AffiliateDisclaimer.importable.tsx new file mode 100644 index 00000000000..86d3c495fba --- /dev/null +++ b/dotcom-rendering/src/components/AffiliateDisclaimer.importable.tsx @@ -0,0 +1,35 @@ +import { css } from '@emotion/react'; +import { space, textSans15 } from '@guardian/source/foundations'; +import { Hide } from '@guardian/source/react-components'; +import { + DisclaimerText, + useAffiliateDisclaimerEvent, +} from '../lib/affiliateDisclaimerHelpers'; + +const disclaimerLeftColStyles = css` + ${textSans15}; + /** + * Typography preset styles should not be overridden. + * This has been done because the styles do not directly map to the new presets. + * Please speak to your team's designer and update this to use a more appropriate preset. + */ + line-height: 1.15; + padding-top: ${space[1]}px; + padding-bottom: ${space[1]}px; +`; + +const AffiliateDisclaimer = () => { + useAffiliateDisclaimerEvent(); + return ( + + + + ); +}; + +export { AffiliateDisclaimer }; diff --git a/dotcom-rendering/src/components/AffiliateDisclaimer.tsx b/dotcom-rendering/src/components/AffiliateDisclaimer.tsx deleted file mode 100644 index 712ebf8d575..00000000000 --- a/dotcom-rendering/src/components/AffiliateDisclaimer.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { css } from '@emotion/react'; -import { - palette, - space, - textSans12, - textSans14, - textSans15, -} from '@guardian/source/foundations'; -import { Hide } from '@guardian/source/react-components'; -import { palette as themePalette } from '../palette'; - -const disclaimerLeftColStyles = css` - ${textSans15}; - /** - * Typography preset styles should not be overridden. - * This has been done because the styles do not directly map to the new presets. - * Please speak to your team's designer and update this to use a more appropriate preset. - */ - line-height: 1.15; - padding-top: ${space[1]}px; - padding-bottom: ${space[1]}px; -`; - -const galleryDisclaimerStyles = css` - ${textSans12}; - line-height: 1.5; - color: ${themePalette('--affiliate-disclaimer-text')}; - a { - color: ${themePalette('--affiliate-disclaimer-text')}; - transition: border-color 0.15s ease-out; - border-bottom: 1px solid ${palette.neutral[46]}; - text-decoration: none; - } - a:hover { - border-bottom: 1px solid - ${themePalette('--affiliate-disclaimer-text-hover')}; - text-decoration: none; - } -`; - -const disclaimerInlineStyles = css` - ${textSans14}; - /** - * Typography preset styles should not be overridden. - * This has been done because the styles do not directly map to the new presets. - * Please speak to your team's designer and update this to use a more appropriate preset. - */ - line-height: 1.15; - float: left; - clear: left; - width: 8.75rem; - background-color: ${themePalette('--affiliate-disclaimer-background')}; - :hover { - background-color: ${themePalette( - '--affiliate-disclaimer-background-hover', - )}; - } - margin-top: ${space[1]}px; - margin-right: ${space[5]}px; - margin-bottom: ${space[1]}px; - padding-top: ${space[0]}px; - padding-right: 5px; - padding-left: 5px; - padding-bottom: ${space[3]}px; -`; - -const DisclaimerText = () => ( -

- The Guardian’s journalism is independent. We will earn a commission if - you buy something through an affiliate link.  - - Learn more - - . -

-); - -const AffiliateDisclaimer = () => ( - - - -); - -const AffiliateDisclaimerInline = () => ( - - - -); - -const GalleryAffiliateDisclaimer = () => ( - -); - -export { - AffiliateDisclaimer, - AffiliateDisclaimerInline, - GalleryAffiliateDisclaimer, -}; diff --git a/dotcom-rendering/src/components/AffiliateDisclaimerInline.importable.tsx b/dotcom-rendering/src/components/AffiliateDisclaimerInline.importable.tsx new file mode 100644 index 00000000000..cadd1e0036d --- /dev/null +++ b/dotcom-rendering/src/components/AffiliateDisclaimerInline.importable.tsx @@ -0,0 +1,50 @@ +import { css } from '@emotion/react'; +import { space, textSans14 } from '@guardian/source/foundations'; +import { Hide } from '@guardian/source/react-components'; +import { + DisclaimerText, + useAffiliateDisclaimerEvent, +} from '../lib/affiliateDisclaimerHelpers'; +import { palette as themePalette } from '../palette'; + +const disclaimerInlineStyles = css` + ${textSans14}; + /** + * Typography preset styles should not be overridden. + * This has been done because the styles do not directly map to the new presets. + * Please speak to your team's designer and update this to use a more appropriate preset. + */ + line-height: 1.15; + float: left; + clear: left; + width: 8.75rem; + background-color: ${themePalette('--affiliate-disclaimer-background')}; + :hover { + background-color: ${themePalette( + '--affiliate-disclaimer-background-hover', + )}; + } + margin-top: ${space[1]}px; + margin-right: ${space[5]}px; + margin-bottom: ${space[1]}px; + padding-top: ${space[0]}px; + padding-right: 5px; + padding-left: 5px; + padding-bottom: ${space[3]}px; +`; + +const AffiliateDisclaimerInline = () => { + useAffiliateDisclaimerEvent(); + return ( + + + + ); +}; + +export { AffiliateDisclaimerInline }; diff --git a/dotcom-rendering/src/components/GalleryAffiliateDisclaimer.importable.tsx b/dotcom-rendering/src/components/GalleryAffiliateDisclaimer.importable.tsx new file mode 100644 index 00000000000..4a7d02592f2 --- /dev/null +++ b/dotcom-rendering/src/components/GalleryAffiliateDisclaimer.importable.tsx @@ -0,0 +1,55 @@ +import { css } from '@emotion/react'; +import { + palette, + space, + textSans12, + textSans15, +} from '@guardian/source/foundations'; +import { + DisclaimerText, + useAffiliateDisclaimerEvent, +} from '../lib/affiliateDisclaimerHelpers'; +import { palette as themePalette } from '../palette'; + +const disclaimerLeftColStyles = css` + ${textSans15}; + /** + * Typography preset styles should not be overridden. + * This has been done because the styles do not directly map to the new presets. + * Please speak to your team's designer and update this to use a more appropriate preset. + */ + line-height: 1.15; + padding-top: ${space[1]}px; + padding-bottom: ${space[1]}px; +`; + +const galleryDisclaimerStyles = css` + ${textSans12}; + line-height: 1.5; + color: ${themePalette('--affiliate-disclaimer-text')}; + a { + color: ${themePalette('--affiliate-disclaimer-text')}; + transition: border-color 0.15s ease-out; + border-bottom: 1px solid ${palette.neutral[46]}; + text-decoration: none; + } + a:hover { + border-bottom: 1px solid + ${themePalette('--affiliate-disclaimer-text-hover')}; + text-decoration: none; + } +`; + +const GalleryAffiliateDisclaimer = () => { + useAffiliateDisclaimerEvent(); + return ( + + ); +}; + +export { GalleryAffiliateDisclaimer }; diff --git a/dotcom-rendering/src/layouts/AudioLayout.tsx b/dotcom-rendering/src/layouts/AudioLayout.tsx index d4327da1612..5dda91e83a5 100644 --- a/dotcom-rendering/src/layouts/AudioLayout.tsx +++ b/dotcom-rendering/src/layouts/AudioLayout.tsx @@ -7,7 +7,7 @@ import { } from '@guardian/source/foundations'; import { StraightLines } from '@guardian/source-development-kitchen/react-components'; import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web'; -import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer'; +import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable'; import { ArticleBody } from '../components/ArticleBody'; import { ArticleContainer } from '../components/ArticleContainer'; import { ArticleHeadline } from '../components/ArticleHeadline'; @@ -272,7 +272,12 @@ export const AudioLayout = (props: WebProps) => { } /> {!!article.affiliateLinksDisclaimer && ( - + + + )} diff --git a/dotcom-rendering/src/layouts/GalleryLayout.tsx b/dotcom-rendering/src/layouts/GalleryLayout.tsx index a2b6480b472..84595e53d7a 100644 --- a/dotcom-rendering/src/layouts/GalleryLayout.tsx +++ b/dotcom-rendering/src/layouts/GalleryLayout.tsx @@ -9,7 +9,6 @@ import { Hide } from '@guardian/source/react-components'; import { AdPlaceholder } from '../components/AdPlaceholder.apps'; import { AdPortals } from '../components/AdPortals.importable'; import { AdSlot } from '../components/AdSlot.web'; -import { GalleryAffiliateDisclaimer } from '../components/AffiliateDisclaimer'; import { AppsFooter } from '../components/AppsFooter.importable'; import { ArticleHeadline } from '../components/ArticleHeadline'; import { ArticleMetaApps } from '../components/ArticleMeta.apps'; @@ -20,6 +19,7 @@ import { DiscussionLayout } from '../components/DiscussionLayout'; import { FetchMoreGalleriesData } from '../components/FetchMoreGalleriesData.importable'; import { Footer } from '../components/Footer'; import { DesktopAdSlot, MobileAdSlot } from '../components/GalleryAdSlots'; +import { GalleryAffiliateDisclaimer } from '../components/GalleryAffiliateDisclaimer.importable'; import { GalleryImage } from '../components/GalleryImage'; import { HeaderAdSlot } from '../components/HeaderAdSlot'; import { Island } from '../components/Island'; @@ -496,7 +496,9 @@ const Meta = ({ /> ) : null} {!!frontendData.affiliateLinksDisclaimer && ( - + + + )} ); diff --git a/dotcom-rendering/src/layouts/ImmersiveLayout.tsx b/dotcom-rendering/src/layouts/ImmersiveLayout.tsx index efdca55a82e..1bf04054dba 100644 --- a/dotcom-rendering/src/layouts/ImmersiveLayout.tsx +++ b/dotcom-rendering/src/layouts/ImmersiveLayout.tsx @@ -9,7 +9,7 @@ import { import { StraightLines } from '@guardian/source-development-kitchen/react-components'; import { AdPortals } from '../components/AdPortals.importable'; import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web'; -import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer'; +import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable'; import { AppsFooter } from '../components/AppsFooter.importable'; import { ArticleBody } from '../components/ArticleBody'; import { ArticleContainer } from '../components/ArticleContainer'; @@ -613,7 +613,12 @@ export const ImmersiveLayout = (props: WebProps | AppProps) => { } /> {!!article.affiliateLinksDisclaimer && ( - + + + )} @@ -643,7 +648,12 @@ export const ImmersiveLayout = (props: WebProps | AppProps) => { } /> {!!article.affiliateLinksDisclaimer && ( - + + + )} )} diff --git a/dotcom-rendering/src/layouts/ShowcaseLayout.tsx b/dotcom-rendering/src/layouts/ShowcaseLayout.tsx index 4fc3ddd4119..cba2b0cf52a 100644 --- a/dotcom-rendering/src/layouts/ShowcaseLayout.tsx +++ b/dotcom-rendering/src/layouts/ShowcaseLayout.tsx @@ -9,7 +9,7 @@ import { Hide } from '@guardian/source/react-components'; import { StraightLines } from '@guardian/source-development-kitchen/react-components'; import { AdPortals } from '../components/AdPortals.importable'; import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web'; -import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer'; +import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable'; import { AppsFooter } from '../components/AppsFooter.importable'; import { ArticleBody } from '../components/ArticleBody'; import { ArticleContainer } from '../components/ArticleContainer'; @@ -490,7 +490,12 @@ export const ShowcaseLayout = (props: WebProps | AppsProps) => { } /> {!!article.affiliateLinksDisclaimer && ( - + + + )} @@ -520,7 +525,12 @@ export const ShowcaseLayout = (props: WebProps | AppsProps) => { } /> {!!article.affiliateLinksDisclaimer && ( - + + + )} )} diff --git a/dotcom-rendering/src/layouts/StandardLayout.tsx b/dotcom-rendering/src/layouts/StandardLayout.tsx index 7510c627882..91f99959bc7 100644 --- a/dotcom-rendering/src/layouts/StandardLayout.tsx +++ b/dotcom-rendering/src/layouts/StandardLayout.tsx @@ -9,7 +9,7 @@ import { Hide } from '@guardian/source/react-components'; import { StraightLines } from '@guardian/source-development-kitchen/react-components'; import { AdPortals } from '../components/AdPortals.importable'; import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web'; -import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer'; +import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable'; import { AppsEpic } from '../components/AppsEpic.importable'; import { AppsFooter } from '../components/AppsFooter.importable'; import { ArticleBody } from '../components/ArticleBody'; @@ -652,7 +652,12 @@ export const StandardLayout = (props: WebProps | AppProps) => { /> {!!article.affiliateLinksDisclaimer && ( - + + + )} @@ -682,7 +687,12 @@ export const StandardLayout = (props: WebProps | AppProps) => { } /> {!!article.affiliateLinksDisclaimer && ( - + + + )} )} diff --git a/dotcom-rendering/src/lib/affiliateDisclaimerHelpers.tsx b/dotcom-rendering/src/lib/affiliateDisclaimerHelpers.tsx new file mode 100644 index 00000000000..93a9aff5b9a --- /dev/null +++ b/dotcom-rendering/src/lib/affiliateDisclaimerHelpers.tsx @@ -0,0 +1,43 @@ +import { useEffect } from 'react'; +import { submitComponentEvent } from '../client/ophan/ophan'; + +/** + * On Articles we render multiple Affiliate Disclaimer components, + * For example one in the left column (for non-mobile breakpoints) + * and one inline (for mobile breakpoints), however we don't want to + * trigger multiple detect events, eg. one event per component, + * one event per Article is desired, we're therefore keeping a record + * of the event being tracked here to achieve this. + */ +let affiliateDisclaimerDetectTracked = false; + +const useAffiliateDisclaimerEvent = (): void => { + useEffect(() => { + if (!affiliateDisclaimerDetectTracked) { + void submitComponentEvent( + { + action: 'DETECT', + component: { + componentType: 'AFFILIATE_DISCLAIMER', + }, + }, + 'Web', + ); + + affiliateDisclaimerDetectTracked = true; + } + }, []); +}; + +const DisclaimerText = () => ( +

+ The Guardian’s journalism is independent. We will earn a commission if + you buy something through an affiliate link.  + + Learn more + + . +

+); + +export { DisclaimerText, useAffiliateDisclaimerEvent }; diff --git a/dotcom-rendering/src/lib/renderElement.tsx b/dotcom-rendering/src/lib/renderElement.tsx index 22132e9ed21..3df1a7335d4 100644 --- a/dotcom-rendering/src/lib/renderElement.tsx +++ b/dotcom-rendering/src/lib/renderElement.tsx @@ -1,5 +1,5 @@ import { AdPlaceholder } from '../components/AdPlaceholder.apps'; -import { AffiliateDisclaimerInline } from '../components/AffiliateDisclaimer'; +import { AffiliateDisclaimerInline } from '../components/AffiliateDisclaimerInline.importable'; import { AudioAtomWrapper } from '../components/AudioAtomWrapper.importable'; import { BlockquoteBlockComponent } from '../components/BlockquoteBlockComponent'; import { CalloutBlockComponent } from '../components/CalloutBlockComponent.importable'; @@ -961,7 +961,11 @@ export const renderElement = ({ ); case 'model.dotcomrendering.pageElements.DisclaimerBlockElement': { - return ; + return ( + + + + ); } case 'model.dotcomrendering.pageElements.CrosswordElement': return (