Skip to content

Commit

Permalink
Merge pull request #12496 from guardian/rm/add-multi-byline
Browse files Browse the repository at this point in the history
Add multi byline element
  • Loading branch information
simonbyford authored Jan 6, 2025
2 parents d6ca01f + ad506b0 commit f63c72c
Show file tree
Hide file tree
Showing 22 changed files with 1,077 additions and 112 deletions.
79 changes: 79 additions & 0 deletions dotcom-rendering/src/components/Bio.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { css } from '@emotion/react';
import { space, textSans14 } from '@guardian/source/foundations';
import sanitise from 'sanitize-html';
import { palette } from '../palette';

/** Nesting is necessary in the bio styles because we receive a string of html from the
* field. This can contain the following tags:
* Blocks: p, ul, li
* Inline: strong, em, a
*/
const bioStyles = css`
${textSans14};
padding: ${space[1]}px 0;
color: ${palette('--bio-text-subdued')};
p {
margin-bottom: ${space[2]}px;
}
a {
color: ${palette('--link-kicker-text')};
text-underline-offset: 3px;
}
a:not(:hover) {
text-decoration-color: ${palette('--bio-link-underline')};
}
a:hover {
text-decoration: underline;
}
ul {
list-style: none;
margin: 0 0 ${space[2]}px;
padding: 0;
}
ul li {
padding-left: ${space[5]}px;
}
ul li p {
display: inline-block;
margin-bottom: 0;
}
ul li:before {
display: inline-block;
content: '';
border-radius: 0.375rem;
height: 10px;
width: 10px;
margin: 0 ${space[2]}px 0 -${space[5]}px;
background-color: ${palette('--bullet-fill')};
}
strong {
font-weight: bold;
}
`;

const bottomBorderStyles = css`
border-top: 1px solid ${palette('--article-border')};
margin-bottom: ${space[2]}px;
`;

const containsText = (html: string) => {
const htmlWithoutTags = sanitise(html, {
allowedTags: [],
allowedAttributes: {},
});
return htmlWithoutTags.length > 0;
};

export const Bio = ({ html }: { html?: string }) => {
if (!html || !containsText(html)) return null;
const sanitizedHtml = sanitise(html, {});
return (
<>
<div
css={bioStyles}
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
/>
<div css={bottomBorderStyles} />
</>
);
};
1 change: 1 addition & 0 deletions dotcom-rendering/src/components/Elements.amp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const listElements = [
'model.dotcomrendering.pageElements.KeyTakeawaysBlockElement',
'model.dotcomrendering.pageElements.ListBlockElement',
'model.dotcomrendering.pageElements.MiniProfilesBlockElement',
'model.dotcomrendering.pageElements.MultiBylinesBlockElement',
'model.dotcomrendering.pageElements.TimelineBlockElement',
'model.dotcomrendering.pageElements.QAndAExplainerBlockElement',
];
Expand Down
18 changes: 18 additions & 0 deletions dotcom-rendering/src/components/EndNote.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { css } from '@emotion/react';
import { space, textSans14 } from '@guardian/source/foundations';
import { palette } from '../palette';

const endNoteStyles = css`
${textSans14};
color: ${palette('--end-note-text-subdued')};
margin-bottom: ${space[3]}px;
`;

export const EndNote = ({ text }: { text?: string }) => {
if (!text) return null;
return (
<p css={endNoteStyles}>
<em>{text}</em>
</p>
);
};
4 changes: 2 additions & 2 deletions dotcom-rendering/src/components/KeyTakeaways.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { css } from '@emotion/react';
import { palette } from '@guardian/source/foundations';
import type { ArticleFormat } from '../lib/articleFormat';
import type { EditionId } from '../lib/edition';
import type { ArticleElementRenderer } from '../lib/renderElement';
import { palette } from '../palette';
import type { ServerSideTests, Switches } from '../types/config';
import type { KeyTakeaway, StarRating } from '../types/content';
import { KeyTakeaway as KeyTakeawayComponent } from './KeyTakeaway';
Expand Down Expand Up @@ -30,7 +30,7 @@ interface KeyTakeawaysProps {
const separatorStyles = css`
width: 140px;
margin: 8px 0 2px 0;
border-top: 1px solid ${palette.neutral[86]};
border-top: 1px solid ${palette('--article-border')};
`;

export const KeyTakeaways = ({
Expand Down
96 changes: 3 additions & 93 deletions dotcom-rendering/src/components/MiniProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { css } from '@emotion/react';
import { neutral, space, textSans14 } from '@guardian/source/foundations';
import sanitise from 'sanitize-html';
import { space } from '@guardian/source/foundations';
import type { ArticleFormat } from '../lib/articleFormat';
import { slugify } from '../model/enhance-H2s';
import { palette } from '../palette';
import type { MiniProfile as MiniProfileModel } from '../types/content';
import { Bio } from './Bio';
import { EndNote } from './EndNote';
import { Heading } from './Heading';
import { headingLineStyles } from './KeyTakeaway';
import { subheadingStyles } from './Subheading';
Expand All @@ -13,65 +13,6 @@ const miniProfileStyles = css`
padding-top: 8px;
`;

/** Nesting is necessary in the bio styles because we receive a string of html from the
* field. This can contain the following tags:
* Blocks: p, ul, li
* Inline: strong, em, a
*/
const bioStyles = css`
${textSans14};
padding: ${space[1]}px 0;
color: ${palette('--mini-profiles-text-subdued')};
p {
margin-bottom: ${space[2]}px;
}
a {
color: ${palette('--link-kicker-text')};
text-underline-offset: 3px;
}
a:not(:hover) {
text-decoration-color: ${neutral[86]};
}
a:hover {
text-decoration: underline;
}
ul {
list-style: none;
margin: 0 0 ${space[2]}px;
padding: 0;
}
ul li {
padding-left: ${space[5]}px;
}
ul li p {
display: inline-block;
margin-bottom: 0;
}
ul li:before {
display: inline-block;
content: '';
border-radius: 0.375rem;
height: 10px;
width: 10px;
margin: 0 ${space[2]}px 0 -${space[5]}px;
background-color: ${palette('--bullet-fill')};
}
strong {
font-weight: bold;
}
`;

const endNoteStyles = css`
${textSans14};
color: ${palette('--mini-profiles-text-subdued')};
margin-bottom: ${space[3]}px;
`;

const bottomBorderStyles = css`
border-top: 1px solid ${palette('--article-border')};
margin-bottom: ${space[2]}px;
`;

const headingMarginStyle = css`
margin-bottom: ${space[2]}px;
`;
Expand Down Expand Up @@ -115,34 +56,3 @@ export const MiniProfile = ({
</>
);
};

const containsText = (html: string) => {
const htmlWithoutTags = sanitise(html, {
allowedTags: [],
allowedAttributes: {},
});
return htmlWithoutTags.length > 0;
};

const Bio = ({ html }: { html?: string }) => {
if (!html || !containsText(html)) return null;
const sanitizedHtml = sanitise(html, {});
return (
<>
<div
css={bioStyles}
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
/>
<div css={bottomBorderStyles} />
</>
);
};

const EndNote = ({ text }: { text?: string }) => {
if (!text) return null;
return (
<p css={endNoteStyles}>
<em>{text}</em>
</p>
);
};
4 changes: 2 additions & 2 deletions dotcom-rendering/src/components/MiniProfiles.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { css } from '@emotion/react';
import { palette } from '@guardian/source/foundations';
import type { ArticleFormat } from '../lib/articleFormat';
import type { EditionId } from '../lib/edition';
import type { ArticleElementRenderer } from '../lib/renderElement';
import { palette } from '../palette';
import type { ServerSideTests, Switches } from '../types/config';
import type { MiniProfile, StarRating } from '../types/content';
import { MiniProfile as MiniProfileComponent } from './MiniProfile';
Expand Down Expand Up @@ -31,7 +31,7 @@ interface MiniProfilesProps {
const separatorStyles = css`
width: 140px;
margin: 8px 0 2px 0;
border-top: 1px solid ${palette.neutral[86]};
border-top: 1px solid ${palette('--article-border')};
`;

export const MiniProfiles = ({
Expand Down
Loading

0 comments on commit f63c72c

Please sign in to comment.