diff --git a/components/x-live-blog-post/readme.md b/components/x-live-blog-post/readme.md index 725846c76..b3d189401 100644 --- a/components/x-live-blog-post/readme.md +++ b/components/x-live-blog-post/readme.md @@ -52,3 +52,5 @@ Feature | Type | Notes `publishedTimestamp`| String | Deprecated - ISO timestamp of publish date `articleUrl` | String | Url of the main article that includes this post `showShareButtons` | Bool | default: `false` - Shows social media share buttons when `true` +`backToTop` | String | Function | Shows the back to top link at the bottom of posts and manages navigating to `selected top` with a javascript function or a hashed href (string). If this prop is a string it will rely on standard browser behaviour to navigate to the element `id` provided that represents the top. If this prop is a function then that function should control the experience of navigating/scrolling to the top position. When using a function please call event.preventDefault() at the top level. + diff --git a/components/x-live-blog-post/src/LiveBlogPost.jsx b/components/x-live-blog-post/src/LiveBlogPost.jsx index 709a822a1..0f217f2ef 100644 --- a/components/x-live-blog-post/src/LiveBlogPost.jsx +++ b/components/x-live-blog-post/src/LiveBlogPost.jsx @@ -1,4 +1,5 @@ -import { h } from '@financial-times/x-engine' +/* eslint-disable jsx-a11y/no-static-element-interactions */ +import { h, Fragment } from '@financial-times/x-engine' import ShareButtons from './ShareButtons' import Timestamp from './Timestamp' import styles from './LiveBlogPost.scss' @@ -17,11 +18,43 @@ const LiveBlogPost = (props) => { articleUrl, showShareButtons = false, byline, - ad + ad, + backToTop } = props const showBreakingNewsLabel = standout.breakingNews || isBreakingNews + let BackToTopComponent + + if (backToTop) { + if (typeof backToTop === 'string') { + const processTopRef = (ref) => { + return ref.includes('#') ? ref : `#${ref}` + } + BackToTopComponent = ( + + Back to top + + ) + } + + if (typeof backToTop === 'function') { + BackToTopComponent = ( + + ) + } + } + return (
{ className={`${styles['live-blog-post__body']} n-content-body article--body`} dangerouslySetInnerHTML={{ __html: bodyHTML || content }} /> - {showShareButtons && } +
+ {showShareButtons && } + {Boolean(BackToTopComponent) && {BackToTopComponent}} +
+ {ad}
) diff --git a/components/x-live-blog-post/src/LiveBlogPost.scss b/components/x-live-blog-post/src/LiveBlogPost.scss index ca983ef58..2e329d21f 100644 --- a/components/x-live-blog-post/src/LiveBlogPost.scss +++ b/components/x-live-blog-post/src/LiveBlogPost.scss @@ -54,10 +54,6 @@ padding-top: oSpacingByName('s1'); } -.live-blog-post__share-buttons { - margin-top: oSpacingByName('s6'); -} - .live-blog-post__breaking-news { @include oTypographySans($scale: -2); color: oColorsByName('crimson'); @@ -74,3 +70,28 @@ border-radius: 50%; background-color: oColorsByName('crimson'); } + +.live-blog-post__controls { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + margin-top: oSpacingByName('s6'); +} + +.live-blog-post__controls .live-blog-post-controls__back-to-top-link, +.live-blog-post__controls .live-blog-post-controls__back-to-top-button { + @include oTypographySans($scale: 1); + color: oColorsByName('teal'); + text-decoration: underline; + margin-left: auto; +} + +.live-blog-post__controls .live-blog-post-controls__back-to-top-button { + background: unset; + border: unset; +} + +.live-blog-post__controls .live-blog-post-controls__back-to-top-button:hover { + cursor: pointer; +} diff --git a/components/x-live-blog-post/src/ShareButtons.jsx b/components/x-live-blog-post/src/ShareButtons.jsx index 0ed3ad888..9c6f3abce 100644 --- a/components/x-live-blog-post/src/ShareButtons.jsx +++ b/components/x-live-blog-post/src/ShareButtons.jsx @@ -1,5 +1,4 @@ import { h } from '@financial-times/x-engine' -import styles from './LiveBlogPost.scss' export default ({ postId, articleUrl, title }) => { const shareUrl = articleUrl ? new URL(articleUrl) : null @@ -18,18 +17,20 @@ export default ({ postId, articleUrl, title }) => { )}&title=${encodeURIComponent(title)}&source=Financial+Times` return ( -
+
+ className="o-share o-share--small" + >