Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSTEAM1-POC: Productionise Hackathon - Easy Read #12245

Draft
wants to merge 15 commits into
base: latest
Choose a base branch
from
1,767 changes: 1,767 additions & 0 deletions data/afrique/articles/c023vz8qn6ro.json

Large diffs are not rendered by default.

1,093 changes: 1,093 additions & 0 deletions data/afrique/articles/c161g3y596go.json

Large diffs are not rendered by default.

7,109 changes: 7,109 additions & 0 deletions data/news/articles/crkdy3r685jo.json

Large diffs are not rendered by default.

7,890 changes: 7,890 additions & 0 deletions data/news/articles/cy0grkwd3zlo.json

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/app/components/EasyReadCTA/config.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* eslint-disable import/prefer-default-export */
export const defaultTranslations = {
aIDisclaimer: `This easy read article has been checked by a journalist. It was created with AI (artificial intelligence) from the standard format.`,
toStandardSite: 'Standard',
toEasySite: 'Easy read',
learnMore: 'Learn more about easy read',
learnMoreLink: 'https://www.bbc.co.uk/',
format: 'Format',
};
31 changes: 31 additions & 0 deletions src/app/components/EasyReadCTA/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { RequestContextProvider } from '#app/contexts/RequestContext';
import EasyReadCTA from '.';

export const Component = () => (
<RequestContextProvider
pathname="/mundo/afrique/cdwrpl7qwqqo"
pageType="article"
service="afrique"
>
<EasyReadCTA
easyReadAssetId="crkdy3r685jo"
originalAssetId="cy0grkwd3zlo"
/>
</RequestContextProvider>
);

export const EasyComponent = () => (
<RequestContextProvider
pathname="/mundo/afrique/cdwrpl7qwqqo"
pageType="article"
service="afrique"
>
<EasyReadCTA originalAssetId="cy0grkwd3zlo" />{' '}
</RequestContextProvider>
);

export default {
title: 'Components/EasyReadCTAVersion2',
Component,
};
92 changes: 92 additions & 0 deletions src/app/components/EasyReadCTA/index.styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { css, Theme } from '@emotion/react';
import pixelsToRem from '../../utilities/pixelsToRem';

// const multicolour = keyframes({
// '0%': { backgroundColor: '#00FFFF' },
// '25%': { backgroundColor: '#39FF14' },
// '50%': { backgroundColor: '#FFFF00' },
// '75%': { backgroundColor: '#FF1493' },
// });

// const changes = keyframes({
// '0%': { backgroundPosition: '0% 50%' },
// '100%': { backgroundPosition: '800% 50%' },
// });

// const shrinkGrowSpin = keyframes({
// '0%': {
// transform: 'scale(3) rotate(0deg)',
// },
// '25%': {
// transform: 'scale(0.5) rotate(90deg)',
// },
// '50%': {
// transform: 'scale(2) rotate(180deg)',
// },
// '75%': {
// transform: 'scale(0.5) rotate(270deg)',
// },
// '100%': {
// transform: 'scale(3) rotate(360deg)',
// },
// });

export default {
icon: ({ palette }: Theme) =>
css({
color: palette.GREY_10,
fill: 'currentColor',
verticalAlign: 'middle',
width: `${pixelsToRem(14)}rem`,
height: `${pixelsToRem(14)}rem`,
}),
linkContainer: ({ spacings }: Theme) =>
css({
textDecoration: 'none',
display: 'inline-block',
padding: `${spacings.FULL}rem 0 ${spacings.DOUBLE}rem 0`,
'&:first-of-type span': {
borderLeft: 'none',
},
}),
linkText: () =>
css({
display: 'inline-block',
textDecoration: 'none',
'a:visited &': {
color: '#141414',
borderBottom: `${pixelsToRem(1)}rem solid #141414`,
},
'a:focus &, a:hover &': {
borderBottom: `${pixelsToRem(2)}rem solid #141414`,
color: '#141414',
},
}),
linkTextContainer: ({ spacings }: Theme) =>
css({
textDecoration: 'none',
display: 'inline-block',
borderLeft: `${pixelsToRem(1)}rem solid #AEAEB5`,
padding: `0 ${spacings.FULL}rem`,
}),
selected: () =>
css({
borderBottom: `${pixelsToRem(2)}rem solid #141414`,
}),
notSelected: () =>
css({
margin: `0 0 ${pixelsToRem(2)}rem 0`,
'a:visited &': {
margin: `0 0 ${pixelsToRem(1)}rem 0`,
},
'a:focus &, a:hover &': {
margin: `0`,
},
}),
disclaimer: ({ spacings }: Theme) =>
css({
padding: `0 0 ${spacings.TRIPLE}rem 0`,
color: '#545658',
display: 'block',
}),
};
31 changes: 31 additions & 0 deletions src/app/components/EasyReadCTA/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { render } from '../react-testing-library-with-providers';
import EasyReadCTA from '.';

describe('LiteSiteCTA', () => {
it('Should have a hidden strong element with lite site identifier.', () => {
const { container } = render(
<EasyReadCTA
easyReadAssetId="crkdy3r685jo"
originalAssetId="cy0grkwd3zlo"
/>,
);
const strongText = container.querySelector('strong');
expect(strongText?.innerHTML).toBe('Format');
expect(strongText).toHaveAttribute('hidden');
});

it('Should have a CTA link to the easy site.', () => {
const { container } = render(
<EasyReadCTA
easyReadAssetId="crkdy3r685jo"
originalAssetId="cy0grkwd3zlo"
/>,
);
const [ctaText] = container.querySelectorAll(
'a[href="/news/articles/crkdy3r685jo"] span span',
);

expect(ctaText?.innerHTML).toBe('Easy read');
});
});
110 changes: 110 additions & 0 deletions src/app/components/EasyReadCTA/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/** @jsx jsx */
import { useContext } from 'react';
import { jsx } from '@emotion/react';
import { GridItemMedium } from '#app/legacy/components/Grid';
import { RequestContext } from '#app/contexts/RequestContext';
import Text from '../Text';
import { ServiceContext } from '../../contexts/ServiceContext';
import styles from './index.styles';
import { defaultTranslations } from './config';
import InlineLink from '../InlineLink';
import { FormatIcon } from '../icons';

type CtaLinkProps = {
href: string;
text: string;
ignoreLiteExtension?: boolean;
className?: string;
selected?: boolean;
};

export const createHrefRelativeToPage = (currentPath: string, id?: string) => {
const noExtenstionPath = currentPath.split('.')[0];
const slugs = noExtenstionPath.split('/');
const idToAppend = id ?? slugs[slugs.length - 1];
slugs.splice(-1, 1, idToAppend);

return slugs.join('/').replace(' ', '');
};

const CtaLink = ({ href, text, className, selected = false }: CtaLinkProps) => {
return (
<a
href={href}
className={className}
css={styles.linkContainer}
{...(selected && { 'aria-current': 'page' })}
>
<span css={styles.linkTextContainer}>
<Text
size="brevier"
css={[
styles.linkText,
selected ? styles.selected : styles.notSelected,
]}
>
{text}
</Text>
</span>
</a>
);
};

type Props = {
easyReadAssetId?: string;
originalAssetId?: string;
};

const EasyReadCTA = ({ easyReadAssetId, originalAssetId }: Props) => {
const { pathname } = useContext(RequestContext);
const { translations } = useContext(ServiceContext);

if (easyReadAssetId == null && originalAssetId == null) {
return null;
}

const easyHref = createHrefRelativeToPage(pathname, easyReadAssetId);
const originalHref = createHrefRelativeToPage(pathname, originalAssetId);

const isEasyActive = easyReadAssetId == null;

const { easyReadSite = defaultTranslations } = translations;
const {
toStandardSite,
toEasySite,
format,
aIDisclaimer,
learnMore,
learnMoreLink,
} = easyReadSite;

const id = 'Format';

return (
<GridItemMedium>
<section role="region" data-e2e="easy-read-cta" aria-labelledby={id}>
<FormatIcon css={styles.icon} />
<Text as="strong" id={id} hidden>
{format}
</Text>
<CtaLink
href={originalHref}
text={toStandardSite}
{...(!isEasyActive && { selected: true })}
/>
<CtaLink
href={easyHref}
text={toEasySite}
{...(isEasyActive && { selected: true })}
/>
</section>
{isEasyActive && (
<Text as="small" size="brevier" css={styles.disclaimer}>
{aIDisclaimer} <InlineLink text={learnMore} to={learnMoreLink} />.
</Text>
)}
</GridItemMedium>
);
};

export default EasyReadCTA;
14 changes: 14 additions & 0 deletions src/app/components/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ export const Ellipsis = () => (
<path d="M1.6 18.8h5.8v-5.6H1.6v5.6zm11.5 0h5.8v-5.6h-5.8v5.6zm11.5 0h5.8v-5.6h-5.8v5.6z" />
</svg>
);

export const FormatIcon = ({ className }: { className?: string }) => (
<svg
viewBox="0 0 32 32"
focusable="false"
aria-hidden="true"
width="12"
height="12"
className={className}
>
<path d="M29.2 1H2.8v30h26.3V1zm-7.6 2.5h5v25H5.4v-25h5l1.7 2.6H20zM10.4 15.6h11.3v-2H10.4zm0 8.3h6v-2h-6zm0-4.1h11.3v-2H10.4z" />
</svg>
);

export const LeftChevron = ({ className }: { className?: string }) => (
<svg
viewBox="0 0 32 32"
Expand Down
12 changes: 12 additions & 0 deletions src/app/lib/config/services/afrique.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ export const service: DefaultServiceConfig = {
relatedContent: 'Lire plus',
relatedTopics: 'Sujets associés',
navMenuText: 'Rubriques',
easyReadSite: {
easyOnboardingMessage: `This is an easy read version of this story.`,
standardOnboardingMessage: `There is an easy read version of this article available.`,
toStandardSite: 'Version standard ',
toEasySite: 'Version facile à lire',
easySite: 'Facile à lire',
standardSite: 'Standard',
format: 'Format',
aIDisclaimer: `Cet article en version facile à lire et à comprendre a été vérifié par un journaliste. Il a été créé avec l'IA (intelligence artificielle) à partir de la version originale. En savoir plus sur la version facile à lire et à comprendre`,
learnMore: 'Learn more about easy read',
learnMoreLink: 'https://www.bbc.co.uk/',
},
mediaAssetPage: {
mediaPlayer: 'Lecteur média',
audioPlayer: 'Lecteur audio',
Expand Down
9 changes: 9 additions & 0 deletions src/app/models/types/optimo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ export type OptimoAltTextBlock = {
};
};

export type EasyReadMetaBlock = {
type: 'easyRead';
model: {
blocks: OptimoBlock[];
};
};

export type OptimoBylineContributorMetadataBlock = {
type: 'name' | 'role' | 'link' | 'location' | 'images';
model: {
Expand All @@ -65,6 +72,8 @@ export type OptimoBylineBlock = {
};

export type ArticleMetadata = {
easyVersionLink?: string;
fullVersionLink?: string;
adCampaignKeyword: string;
allowAdvertising: boolean;
analyticsLabels?: {
Expand Down
12 changes: 12 additions & 0 deletions src/app/models/types/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ export interface Translations {
informationPageLink: string;
dataSaving: string;
};
easyReadSite?: {
easyOnboardingMessage: string;
standardOnboardingMessage: string;
toStandardSite: string;
toEasySite: string;
easySite: string;
standardSite: string;
format: string;
aIDisclaimer: string;
learnMore: string;
learnMoreLink: string;
};
mediaAssetPage: {
mediaPlayer: string;
audioPlayer: string;
Expand Down
Loading
Loading