updates SiteFooter, replacing referrals with ReferralBlock. Also centres ReferralBlock

This commit is contained in:
hobbes7878 2024-11-19 16:53:43 +00:00
parent e0ea86c5fb
commit 59c56f7742
10 changed files with 88 additions and 362 deletions

View file

@ -8,7 +8,7 @@
"type": "git",
"url": "git+https://github.com/reuters-graphics/graphics-components.git"
},
"packageManager": "pnpm@9.6.0",
"packageManager": "pnpm@9.13.2",
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"

View file

@ -48,7 +48,6 @@
import Block from '../Block/Block.svelte';
import { onMount } from 'svelte';
import { getTime } from '../SiteHeader/NavBar/NavDropdown/StoryCard/time';
let clientWidth: number;
@ -57,7 +56,7 @@
let referrals = [];
onMount(async () => {
const getReferrals = async () => {
const isCollection = Boolean(collection);
const API = isCollection ? COLLECTION_API : SECTION_API;
try {
@ -82,74 +81,79 @@
} catch {
console.warn('Unable to fetch referral links.');
}
});
};
getTime();
onMount(getReferrals);
</script>
{#if referrals.length === number}
<Block {width} {id} class="referrals-block {cls}">
{#if heading}
<div
class="heading h4 font-bold"
class:stacked="{clientWidth && clientWidth < 750}"
>
{heading}
</div>
{/if}
<div
class="referral-container inline-flex flex-wrap w-full justify-between"
class="block-container"
class:stacked="{clientWidth && clientWidth < 750}"
class:xs="{clientWidth && clientWidth < 450}"
bind:clientWidth
>
{#each referrals as referral}
<div class="referral">
<a
href="https://www.reuters.com{referral.canonical_url}"
target="{linkTarget}"
rel="{linkTarget === '_blank' ? 'noreferrer' : null}"
>
<div class="referral-pack flex justify-around my-0 mx-auto">
<div
class="headline"
class:xs="{clientWidth && clientWidth < 450}"
>
<div
class="kicker m-0 body-caption leading-tighter"
data-chromatic="ignore"
>
{referral.headline_category || referral.kicker.name}
</div>
<div
class="title m-0 body-caption leading-tighter"
data-chromatic="ignore"
>
{referral.title}
</div>
<div
class="publish-time body-caption leading-tighter"
data-chromatic="ignore"
>
{getTime(new Date(referral.display_time))}
</div>
</div>
<div
class="image-container block m-0 overflow-hidden relative"
class:xs="{clientWidth && clientWidth < 450}"
>
<img
class="block object-cover m-0 w-full"
data-chromatic="ignore"
src="{referral.thumbnail.renditions.landscape['240w']}"
alt="{referral.thumbnail.caption ||
referral.thumbnail.alt_text}"
/>
</div>
</div>
</a>
{#if heading}
<div
class="heading h4 font-bold"
class:stacked="{clientWidth && clientWidth < 750}"
>
{heading}
</div>
{/each}
{/if}
<div
class="referral-container inline-flex flex-wrap w-full justify-between"
class:stacked="{clientWidth && clientWidth < 750}"
class:xs="{clientWidth && clientWidth < 450}"
>
{#each referrals as referral}
<div class="referral">
<a
href="https://www.reuters.com{referral.canonical_url}"
target="{linkTarget}"
rel="{linkTarget === '_blank' ? 'noreferrer' : null}"
>
<div class="referral-pack flex justify-around my-0 mx-auto">
<div
class="headline"
class:xs="{clientWidth && clientWidth < 450}"
>
<div
class="kicker m-0 body-caption leading-tighter"
data-chromatic="ignore"
>
{referral.headline_category || referral.kicker.name}
</div>
<div
class="title m-0 body-caption leading-tighter"
data-chromatic="ignore"
>
{referral.title}
</div>
<div
class="publish-time body-caption leading-tighter"
data-chromatic="ignore"
>
{getTime(new Date(referral.display_time))}
</div>
</div>
<div
class="image-container block m-0 overflow-hidden relative"
class:xs="{clientWidth && clientWidth < 450}"
>
<img
class="block object-cover m-0 w-full"
data-chromatic="ignore"
src="{referral.thumbnail.renditions.landscape['240w']}"
alt="{referral.thumbnail.caption ||
referral.thumbnail.alt_text}"
/>
</div>
</div>
</a>
</div>
{/each}
</div>
</div>
</Block>
{/if}
@ -157,7 +161,14 @@
<style lang="scss">
@use '../../scss/mixins' as *;
div.block-container.stacked {
display: flex;
flex-direction: column;
align-items: center;
}
div.heading {
margin-top: 0;
&.stacked {
max-width: 450px;
}
@ -168,6 +179,7 @@
text-decoration: none;
}
&.stacked {
max-width: 450px;
.referral {
width: 100%;
.headline {
@ -194,8 +206,6 @@
display: inline-block;
width: calc(100% - 9rem);
@include fpr-2;
&.xs {
}
.kicker {
@include text-xxs;
}

View file

@ -1,45 +0,0 @@
<script>
import { onMount } from 'svelte';
export let once = false;
export let top = 0;
export let bottom = 0;
export let left = 0;
export let right = 0;
let intersecting = false;
let container;
onMount(() => {
if (typeof IntersectionObserver !== 'undefined') {
const rootMargin = `${bottom}px ${left}px ${top}px ${right}px`;
const observer = new IntersectionObserver(
(entries) => {
intersecting = entries[0].isIntersecting;
if (intersecting && once) {
observer.unobserve(container);
}
},
{
rootMargin,
}
);
observer.observe(container);
return () => observer.unobserve(container);
}
function handler() {
const bcr = container.getBoundingClientRect();
intersecting =
bcr.bottom + bottom > 0 &&
bcr.right + right > 0 &&
bcr.top - top < window.innerHeight &&
bcr.left - left < window.innerWidth;
if (intersecting && once) {
window.removeEventListener('scroll', handler);
}
}
window.addEventListener('scroll', handler);
return () => window.removeEventListener('scroll', handler);
});
</script>
<div bind:this="{container}">
<slot {intersecting} />
</div>

View file

@ -1,83 +0,0 @@
<script>
import IntersectionObserver from './IntersectionObserver.svelte';
export let url;
export let image;
export let title;
export let description;
</script>
<div class="referral py-0 px-3" title="{description}">
<a href="{url.replace('index.html', '')}">
<IntersectionObserver let:intersecting top="{600}" once="{true}">
{#if intersecting}
<div
data-chromatic="ignore"
class="image"
style="{`background-image: url(${image});`}"
></div>
{:else}
<div class="image"></div>
{/if}
</IntersectionObserver>
<p class="body-caption font-bold leading-tighter" data-chromatic="ignore">
{title}
</p>
</a>
</div>
<!-- svelte-ignore css-unused-selector -->
<style lang="scss">
@import '../../../scss/mixins';
a {
text-decoration: none;
}
.image {
width: 100%;
padding-bottom: 50%;
background-size: cover;
background-position: 50%;
}
.referral {
padding: 0 0.75rem;
div.image {
@include fmb-1;
border: 1px solid var(--nav-rules, #efefef);
border-radius: 0.25rem;
}
a:hover {
text-decoration: none;
p {
text-decoration: underline;
}
}
p {
color: var(--nav-primary, #666);
text-transform: none;
margin: 0;
}
width: 25%;
// padding: 0 10px;
@media (max-width: 768px) {
width: 33.33333%;
&:nth-child(4) {
display: none;
}
}
@media (max-width: 575px) {
width: 50%;
&:nth-child(3) {
display: none;
}
}
}
</style>

View file

@ -1,58 +0,0 @@
<script>
import { onMount } from 'svelte';
import Link from './Link.svelte';
export let referrals = [];
$: verifiedReferrals = referrals
.filter((r) => r.url && r.title && r.image)
.slice(0, 4);
let metadata;
onMount(() => {
if (verifiedReferrals.length === 4) {
metadata = verifiedReferrals;
return;
}
fetch(
'https://graphics.thomsonreuters.com/data/reuters-graphics/homepage/graphics.json'
)
.then((resp) => resp.json())
.then((d) => {
const data = d
.filter(({ canonical }) => {
const pathname = window.location.pathname
.replace(/\/index\.html$/, '')
.replace(/\/$/, '');
if (!pathname) return true;
return !canonical.includes(pathname);
})
.slice(0, 4)
.map(({ url, image, title, description }) => ({
url,
image,
title,
description,
}));
metadata = [...verifiedReferrals, ...data].slice(0, 4);
});
});
</script>
{#if metadata}
<nav class="referral-rail row">
{#each metadata as referral}
<Link {...referral} />
{/each}
</nav>
{/if}
<style lang="scss">
.row {
margin-right: -10px;
margin-left: -10px;
display: flex;
flex-wrap: wrap;
}
</style>

View file

@ -1,42 +0,0 @@
<script>
import Referrals from './Referrals.svelte';
import IntersectionObserver from './IntersectionObserver.svelte';
export let referrals = [];
</script>
<IntersectionObserver let:intersecting top="{2400}" once="{true}">
{#if intersecting}
<section class="referrals px-0 py-5">
<h2 class="fmt-0 text-base font-medium">
<a href="https://graphics.reuters.com/">More from Reuters Graphics</a>
</h2>
{#if typeof window !== 'undefined'}
<Referrals {referrals} />
{/if}
</section>
{/if}
</IntersectionObserver>
<style lang="scss">
@import '../../SiteHeader/scss/_breakpoints.scss';
@import '../../SiteHeader/scss/_grids.scss';
section.referrals {
margin: 0;
max-width: 1400px;
@include spacing-single(padding-left padding-right);
border-top: 1px solid var(--nav-rules, #999);
h2 {
color: var(--nav-primary, #666);
a {
color: var(--nav-primary, #666);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
</style>

View file

@ -6,8 +6,6 @@
// @ts-ignore raw
import darkThemeDocs from './stories/docs/darkTheme.md?raw';
// @ts-ignore raw
import customReferralsDocs from './stories/docs/customReferrals.md?raw';
// @ts-ignore raw
import removeReferralsDocs from './stories/docs/removeReferrals.md?raw';
import SiteFooter from './SiteFooter.svelte';
@ -17,23 +15,6 @@
withComponentDocs,
withStoryDocs,
} from '$lib/docs/utils/withParams.js';
const customReferrals = [
{
url: 'https://graphics.reuters.com/world-coronavirus-tracker-and-maps/',
title: 'COVID-19: the latest global statistics, charts and maps',
description: 'Tracking the global coronavirus outbreak, updated daily',
image:
'https://graphics.thomsonreuters.com/cdn/2020/covid-global-tracker/share-cards/global/en/share.png',
},
{
url: 'https://graphics.reuters.com/world-coronavirus-tracker-and-maps/regions/europe',
title: 'Coronavirus in Europe: the latest counts, charts and maps',
description: 'Tracking the global coronavirus outbreak, updated daily',
image:
'https://graphics.thomsonreuters.com/cdn/2020/covid-global-tracker/share-cards/regions/en/europe.png',
},
];
</script>
<Meta
@ -58,14 +39,6 @@
</div>
</Story>
<Story
name="Customised referrals"
args="{{
referrals: customReferrals,
}}"
{...withStoryDocs(customReferralsDocs)}
/>
<Story
name="Remove referrals"
args="{{ includeReferrals: false }}"

View file

@ -3,23 +3,12 @@
import QuickLinks from './QuickLinks.svelte';
import CompanyLinks from './CompanyLinks.svelte';
import LegalLinks from './LegalLinks.svelte';
import Referrals from './Referrals/index.svelte';
import ReferralBlock from '../ReferralBlock/ReferralBlock.svelte';
import PaddingReset from '../PaddingReset/PaddingReset.svelte';
import starterData from './data.json';
import { onMount } from 'svelte';
interface Referral {
url: URL;
image: URL;
title: string;
description?: string;
}
/**
* Custom referrals to other Reuters Graphics projects
*/
export let referrals: Referral[] = [];
/**
* Set to `false` to remove graphics referrals
*/
@ -60,7 +49,13 @@
>
<div>
{#if includeReferrals}
<Referrals {referrals} />
<PaddingReset>
<ReferralBlock
heading="More from Reuters Graphics"
collection="graphics"
class="fpy-4"
/>
</PaddingReset>
{/if}
<QuickLinks links="{data[0]}" />
<CompanyLinks links="{data[0]}" />

View file

@ -1,26 +0,0 @@
Pass up to four custom referrals to the `referrals` prop.
```svelte
<script>
import { SiteFooter } from '@reuters-graphics/graphics-components';
const customReferrals = [
{
url: 'https://graphics.reuters.com/world-coronavirus-tracker-and-maps/',
title: 'COVID-19: the latest global statistics, charts and maps',
description: 'Tracking the global coronavirus outbreak, updated daily',
image:
'https://graphics.thomsonreuters.com/cdn/2020/covid-global-tracker/share-cards/global/en/share.png',
},
{
url: 'https://graphics.reuters.com/world-coronavirus-tracker-and-maps/regions/europe',
title: 'Coronavirus in Europe: the latest counts, charts and maps',
description: 'Tracking the global coronavirus outbreak, updated daily',
image:
'https://graphics.thomsonreuters.com/cdn/2020/covid-global-tracker/share-cards/regions/en/europe.png',
},
];
</script>
<SiteFooter referrals="{customReferrals}" />
```

View file

@ -3,13 +3,15 @@
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 30 30"
aria-labelledby="TwitterIconId"
role="presentation"
aria-hidden="true"
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 13"
style="width: {width}px;"
><path
d="M16 1.537a6.469 6.469 0 0 1-1.884.516A3.3 3.3 0 0 0 15.559.237a6.603 6.603 0 0 1-2.084.797A3.282 3.282 0 0 0 11.078 0a3.28 3.28 0 0 0-3.196 4.028A9.315 9.315 0 0 1 1.118.598a3.28 3.28 0 0 0-.444 1.65c0 1.137.578 2.143 1.46 2.73A3.281 3.281 0 0 1 .646 4.57v.04A3.282 3.282 0 0 0 3.28 7.83a3.286 3.286 0 0 1-1.483.055 3.294 3.294 0 0 0 3.065 2.282A6.583 6.583 0 0 1 0 11.526 9.281 9.281 0 0 0 5.034 13c6.036 0 9.338-5.003 9.338-9.34 0-.144-.003-.285-.01-.425A6.607 6.607 0 0 0 16 1.538Z"
><title id="TwitterIconId">X</title><path
d="M17.923 14.387 25.569 5.5h-1.812l-6.64 7.717L11.817 5.5H5.7l8.018 11.67L5.7 26.49h1.812l7.01-8.15 5.6 8.15h6.116l-8.316-12.102Zm-2.482 2.885-.812-1.162-6.464-9.246h2.783l5.216 7.462.813 1.162 6.78 9.7h-2.782l-5.534-7.915Z"
></path></svg
>