@reuters-graphics/graphics-components 3.0.5 → 3.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Analytics/Analytics.svelte +1 -4
- package/dist/components/Analytics/providers/index.d.ts +0 -1
- package/dist/components/Analytics/providers/index.js +0 -1
- package/dist/components/Headpile/Headpile.mdx +37 -0
- package/dist/components/Headpile/Headpile.stories.svelte +37 -0
- package/dist/components/Headpile/Headpile.stories.svelte.d.ts +19 -0
- package/dist/components/Headpile/Headpile.svelte +84 -0
- package/dist/components/Headpile/Headpile.svelte.d.ts +53 -0
- package/dist/components/Headpile/Headshot.svelte +41 -0
- package/dist/components/Headpile/Headshot.svelte.d.ts +6 -0
- package/dist/components/Headpile/KeyFigure.svelte +110 -0
- package/dist/components/Headpile/KeyFigure.svelte.d.ts +10 -0
- package/dist/components/Headpile/images/abdel.png +0 -0
- package/dist/components/Headpile/images/hemedti.png +0 -0
- package/dist/components/ScrollerBase/ScrollerBase.svelte +1 -1
- package/dist/components/ScrollerBase/demo/ScrollerDemo.svelte +2 -1
- package/dist/components/Visible/Visible.mdx +2 -1
- package/dist/components/Visible/Visible.stories.svelte +3 -10
- package/dist/components/Visible/Visible.svelte +20 -30
- package/dist/components/Visible/Visible.svelte.d.ts +8 -8
- package/dist/components/Visible/demo/VisibleDemo.svelte +46 -0
- package/dist/components/Visible/demo/VisibleDemo.svelte.d.ts +3 -0
- package/dist/globals.d.ts +0 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/dist/components/Analytics/providers/parsely.d.ts +0 -3
- package/dist/components/Analytics/providers/parsely.js +0 -29
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
<script module>
|
|
4
4
|
import { registerPageview as registerChartbeatPageview } from './providers/chartbeat';
|
|
5
5
|
import { registerPageview as registerGAPageview } from './providers/ga';
|
|
6
|
-
import { registerPageview as registerParselyPageview } from './providers/parsely';
|
|
7
6
|
|
|
8
7
|
/** Register virtual pageviews when using client-side routing in multipage applications. */
|
|
9
8
|
function registerPageview() {
|
|
10
9
|
registerChartbeatPageview();
|
|
11
10
|
registerGAPageview();
|
|
12
|
-
registerParselyPageview();
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
export { registerPageview };
|
|
@@ -21,7 +19,7 @@
|
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
import { onMount } from 'svelte';
|
|
24
|
-
import { ga, chartbeat
|
|
22
|
+
import { ga, chartbeat } from './providers';
|
|
25
23
|
interface Props {
|
|
26
24
|
/**
|
|
27
25
|
* Used to associate a page with its author(s) in Chartbeat.
|
|
@@ -34,6 +32,5 @@
|
|
|
34
32
|
onMount(() => {
|
|
35
33
|
ga();
|
|
36
34
|
chartbeat(authors);
|
|
37
|
-
parsely();
|
|
38
35
|
});
|
|
39
36
|
</script>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Meta, Canvas } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import * as HeadpileStories from './Headpile.stories.svelte';
|
|
4
|
+
|
|
5
|
+
<Meta of={HeadpileStories} />
|
|
6
|
+
|
|
7
|
+
# Headpile
|
|
8
|
+
|
|
9
|
+
The `Headpile` component is a headshot-bulleted list of people, identifying them with their names, roles and a short description of their significance to a story.
|
|
10
|
+
|
|
11
|
+
It's designed to be used with headshots that have had their background removed, which can be done in the [Preview app](https://support.apple.com/en-gb/guide/preview/prvw15636/mac?#apd320b3b1b750a4) on macOS.
|
|
12
|
+
|
|
13
|
+
```svelte
|
|
14
|
+
<script>
|
|
15
|
+
import { Headpile } from '@reuters-graphics/graphics-components';
|
|
16
|
+
import { assets } from '$app/paths'; // 👈 If using in the graphics kit...
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<Headpile
|
|
20
|
+
figures={[
|
|
21
|
+
{
|
|
22
|
+
img: `${assets}/images/person-A.jpg`,
|
|
23
|
+
name: 'General Abdel Fattah al-Burhan',
|
|
24
|
+
role: "Sudan's Sovereign Council Chief and military commander",
|
|
25
|
+
text: 'Burhan was little known in public life until taking part in the coup ...',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
img: `${assets}/images/person-B.jpg`,
|
|
29
|
+
name: 'General Mohamed Hamdan Dagalo',
|
|
30
|
+
role: 'Leader of the Sudanese paramilitary Rapid Support Forces (RSF)',
|
|
31
|
+
text: 'Popularly known as Hemedti, Dagalo rose from lowly beginnings ...',
|
|
32
|
+
},
|
|
33
|
+
]}
|
|
34
|
+
/>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
<Canvas of={HeadpileStories.Demo} />
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Headpile from './Headpile.svelte';
|
|
4
|
+
|
|
5
|
+
import hed1 from './images/abdel.png';
|
|
6
|
+
import hed2 from './images/hemedti.png';
|
|
7
|
+
|
|
8
|
+
const { Story } = defineMeta({
|
|
9
|
+
title: 'Components/Text elements/Headpile',
|
|
10
|
+
component: Headpile,
|
|
11
|
+
argTypes: {},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const defaultArgs = [
|
|
15
|
+
{
|
|
16
|
+
name: 'General Abdel Fattah al-Burhan',
|
|
17
|
+
role: "Sudan's Sovereign Council Chief and military commander",
|
|
18
|
+
img: hed1,
|
|
19
|
+
text: 'Burhan was little known in public life until taking part in the coup against Bashir in 2019 after a popular uprising against his rule. In August 2019, his role as de facto head of state was affirmed when he became head of the Sovereign Council, a body comprising civilian and military leaders formed to oversee the transition towards elections.',
|
|
20
|
+
// colour: '#957caa',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'General Mohamed Hamdan Dagalo',
|
|
24
|
+
role: 'Leader of the Sudanese paramilitary Rapid Support Forces (RSF)',
|
|
25
|
+
img: hed2,
|
|
26
|
+
text: "Popularly known as Hemedti, Dagalo rose from lowly beginnings as a camel trader to head a widely feared Arab militia that crushed a revolt in Darfur, winning him influence and eventually a role as Sudan's former deputy head of state.\r\n\r\nOver the past decade, he has been a key figure in Sudanese politics, aiding in the ousting of Bashir in 2019 and suppressing pro-democracy protests. As the country limped from one economic crisis to another, Hemedti became one of Sudan’s richest men, exporting gold from mines in Darfur seized by his fighters.",
|
|
27
|
+
colour: '#afb776',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<Story
|
|
33
|
+
name="Demo"
|
|
34
|
+
args={{
|
|
35
|
+
figures: defaultArgs,
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Headpile from './Headpile.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Headpile: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type Headpile = InstanceType<typeof Headpile>;
|
|
19
|
+
export default Headpile;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ContainerWidth } from '../@types/global';
|
|
3
|
+
import Block from '../Block/Block.svelte';
|
|
4
|
+
import KeyFigure from './KeyFigure.svelte';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
/**
|
|
8
|
+
* Add classes to target with custom CSS.
|
|
9
|
+
*/
|
|
10
|
+
class: string;
|
|
11
|
+
/**
|
|
12
|
+
* Add an id to target with custom CSS.
|
|
13
|
+
*/
|
|
14
|
+
id: string;
|
|
15
|
+
/**
|
|
16
|
+
* Width of the container.
|
|
17
|
+
*/
|
|
18
|
+
width: Extract<ContainerWidth, 'normal' | 'wide'>;
|
|
19
|
+
/**
|
|
20
|
+
* Default background colour to be used as a mount behind the headshot.
|
|
21
|
+
*/
|
|
22
|
+
colour: string;
|
|
23
|
+
/**
|
|
24
|
+
* Individual figures -- i.e., people -- for the headpile.
|
|
25
|
+
*/
|
|
26
|
+
figures: {
|
|
27
|
+
/**
|
|
28
|
+
* Headshot image src. Be sure to prefix the image
|
|
29
|
+
*
|
|
30
|
+
* ```typescript
|
|
31
|
+
* import { assets } from '$app/paths';
|
|
32
|
+
*
|
|
33
|
+
* const imgSrc = `${assets}/images/my-image.jpg`;
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
img: string;
|
|
37
|
+
/**
|
|
38
|
+
* Figure name.
|
|
39
|
+
*/
|
|
40
|
+
name: string;
|
|
41
|
+
/**
|
|
42
|
+
* Figure role or title.
|
|
43
|
+
*/
|
|
44
|
+
role?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Text describing the person.
|
|
47
|
+
*/
|
|
48
|
+
text: string;
|
|
49
|
+
/**
|
|
50
|
+
* Background colour to be used as a mount behind the headshot.
|
|
51
|
+
*/
|
|
52
|
+
colour?: string;
|
|
53
|
+
}[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let {
|
|
57
|
+
figures,
|
|
58
|
+
class: cls,
|
|
59
|
+
id,
|
|
60
|
+
width = 'normal',
|
|
61
|
+
colour = '#cccccc',
|
|
62
|
+
}: Props = $props();
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<Block class="fmy-6 {cls} {id} {width}">
|
|
66
|
+
<div class="figures">
|
|
67
|
+
{#each figures as figure}
|
|
68
|
+
<KeyFigure {...{ ...figure, colour: figure.colour ?? colour }} />
|
|
69
|
+
{/each}
|
|
70
|
+
</div>
|
|
71
|
+
</Block>
|
|
72
|
+
|
|
73
|
+
<style>/* Generated from
|
|
74
|
+
https://utopia.fyi/space/calculator/?c=320,18,1.125,1280,21,1.25,7,3,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12
|
|
75
|
+
*/
|
|
76
|
+
/* Generated from
|
|
77
|
+
https://utopia.fyi/space/calculator/?c=320,18,1.125,1280,21,1.25,7,3,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12
|
|
78
|
+
*/
|
|
79
|
+
/* Scales by 1.125 */
|
|
80
|
+
div.figures {
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
gap: 2.75rem;
|
|
84
|
+
}</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ContainerWidth } from '../@types/global';
|
|
2
|
+
interface Props {
|
|
3
|
+
/**
|
|
4
|
+
* Add classes to target with custom CSS.
|
|
5
|
+
*/
|
|
6
|
+
class: string;
|
|
7
|
+
/**
|
|
8
|
+
* Add an id to target with custom CSS.
|
|
9
|
+
*/
|
|
10
|
+
id: string;
|
|
11
|
+
/**
|
|
12
|
+
* Width of the container.
|
|
13
|
+
*/
|
|
14
|
+
width: Extract<ContainerWidth, 'normal' | 'wide'>;
|
|
15
|
+
/**
|
|
16
|
+
* Default background colour to be used as a mount behind the headshot.
|
|
17
|
+
*/
|
|
18
|
+
colour: string;
|
|
19
|
+
/**
|
|
20
|
+
* Individual figures -- i.e., people -- for the headpile.
|
|
21
|
+
*/
|
|
22
|
+
figures: {
|
|
23
|
+
/**
|
|
24
|
+
* Headshot image src. Be sure to prefix the image
|
|
25
|
+
*
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { assets } from '$app/paths';
|
|
28
|
+
*
|
|
29
|
+
* const imgSrc = `${assets}/images/my-image.jpg`;
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
img: string;
|
|
33
|
+
/**
|
|
34
|
+
* Figure name.
|
|
35
|
+
*/
|
|
36
|
+
name: string;
|
|
37
|
+
/**
|
|
38
|
+
* Figure role or title.
|
|
39
|
+
*/
|
|
40
|
+
role?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Text describing the person.
|
|
43
|
+
*/
|
|
44
|
+
text: string;
|
|
45
|
+
/**
|
|
46
|
+
* Background colour to be used as a mount behind the headshot.
|
|
47
|
+
*/
|
|
48
|
+
colour?: string;
|
|
49
|
+
}[];
|
|
50
|
+
}
|
|
51
|
+
declare const Headpile: import("svelte").Component<Props, {}, "">;
|
|
52
|
+
type Headpile = ReturnType<typeof Headpile>;
|
|
53
|
+
export default Headpile;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let { img = '', colour = 'var(--theme-colour-accent)' } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="headshot-wrapper">
|
|
6
|
+
<div class="background" style="background-color: {colour};"></div>
|
|
7
|
+
<div class="headshot" style="background-image: url({img}); "></div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<style>.headshot-wrapper {
|
|
11
|
+
width: 7rem;
|
|
12
|
+
height: 6.75rem;
|
|
13
|
+
position: relative;
|
|
14
|
+
margin-block-start: -1.75rem;
|
|
15
|
+
margin-block-end: -1.75rem;
|
|
16
|
+
border-radius: 0.25rem;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.background {
|
|
21
|
+
position: absolute;
|
|
22
|
+
inset-block-end: 0;
|
|
23
|
+
inset-inline-start: 0;
|
|
24
|
+
width: 7rem;
|
|
25
|
+
height: 4.75rem;
|
|
26
|
+
display: inline-block;
|
|
27
|
+
border-radius: 0.25rem;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.headshot {
|
|
31
|
+
display: inline-block;
|
|
32
|
+
width: 100%;
|
|
33
|
+
height: 100%;
|
|
34
|
+
background-size: 106%;
|
|
35
|
+
background-position: center bottom;
|
|
36
|
+
background-repeat: no-repeat;
|
|
37
|
+
position: absolute;
|
|
38
|
+
inset-block-end: 0;
|
|
39
|
+
inset-inline-start: 0;
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
}</style>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Markdown } from '@reuters-graphics/svelte-markdown';
|
|
3
|
+
import Headshot from './Headshot.svelte';
|
|
4
|
+
import { MediaQuery } from 'svelte/reactivity';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
img: string;
|
|
8
|
+
name: string;
|
|
9
|
+
role?: string;
|
|
10
|
+
text: string;
|
|
11
|
+
colour?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let { name, role, img, text, colour }: Props = $props();
|
|
15
|
+
|
|
16
|
+
const mobile = new MediaQuery('max-width: 600px');
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<div>
|
|
20
|
+
<div class="wrapper-profile">
|
|
21
|
+
<div>
|
|
22
|
+
<Headshot {img} {colour} />
|
|
23
|
+
</div>
|
|
24
|
+
<div class="text">
|
|
25
|
+
<div class="title">{name}</div>
|
|
26
|
+
<div class="role">
|
|
27
|
+
{role || ''}
|
|
28
|
+
</div>
|
|
29
|
+
{#if !mobile.current}
|
|
30
|
+
<div class="description desktop">
|
|
31
|
+
<Markdown source={text} />
|
|
32
|
+
</div>
|
|
33
|
+
{/if}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
{#if mobile.current}
|
|
38
|
+
<div class="description mobile">
|
|
39
|
+
<Markdown source={text} />
|
|
40
|
+
</div>
|
|
41
|
+
{/if}
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<style>/* Generated from
|
|
45
|
+
https://utopia.fyi/space/calculator/?c=320,18,1.125,1280,21,1.25,7,3,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12
|
|
46
|
+
*/
|
|
47
|
+
/* Generated from
|
|
48
|
+
https://utopia.fyi/space/calculator/?c=320,18,1.125,1280,21,1.25,7,3,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12
|
|
49
|
+
*/
|
|
50
|
+
/* Scales by 1.125 */
|
|
51
|
+
.wrapper-profile {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: flex-start;
|
|
54
|
+
justify-content: start;
|
|
55
|
+
gap: 1rem;
|
|
56
|
+
width: 100%;
|
|
57
|
+
min-height: 5.5rem;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.title {
|
|
61
|
+
font-weight: 700;
|
|
62
|
+
font-size: var(--theme-font-size-base);
|
|
63
|
+
line-height: 1;
|
|
64
|
+
}
|
|
65
|
+
@media (max-width: 450px) {
|
|
66
|
+
.title {
|
|
67
|
+
font-size: calc(0.9 * var(--theme-font-size-base, 1rem));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.role {
|
|
72
|
+
border-block-start: 0.5px solid var(--tr-muted-grey);
|
|
73
|
+
margin-inline-start: -0.75rem;
|
|
74
|
+
padding-inline-start: 0.75rem;
|
|
75
|
+
margin-block-start: 0.25rem;
|
|
76
|
+
padding-block-start: 0.25rem;
|
|
77
|
+
font-family: var(--theme-font-family-note);
|
|
78
|
+
color: var(--theme-colour-text-secondary);
|
|
79
|
+
font-size: var(--theme-font-size-sm);
|
|
80
|
+
font-weight: 300;
|
|
81
|
+
line-height: 1.15;
|
|
82
|
+
margin-block-end: clamp(1.13rem, 1.06rem + 0.31vw, 1.31rem);
|
|
83
|
+
}
|
|
84
|
+
@media (max-width: 450px) {
|
|
85
|
+
.role {
|
|
86
|
+
font-size: var(--theme-font-size-xs);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.description :global(p) {
|
|
91
|
+
font-family: var(--theme-font-family-note);
|
|
92
|
+
font-size: calc(0.9 * var(--theme-font-size-base, 1rem));
|
|
93
|
+
font-weight: 300;
|
|
94
|
+
margin-block-end: 0;
|
|
95
|
+
text-wrap: pretty;
|
|
96
|
+
}
|
|
97
|
+
.description.desktop {
|
|
98
|
+
display: block;
|
|
99
|
+
}
|
|
100
|
+
.description.mobile {
|
|
101
|
+
display: none;
|
|
102
|
+
}
|
|
103
|
+
@media (max-width: 600px) {
|
|
104
|
+
.description.desktop {
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
.description.mobile {
|
|
108
|
+
display: block;
|
|
109
|
+
}
|
|
110
|
+
}</style>
|
|
Binary file
|
|
Binary file
|
|
@@ -67,8 +67,9 @@ https://utopia.fyi/space/calculator/?c=320,18,1.125,1280,21,1.25,7,3,&s=0.75|0.5
|
|
|
67
67
|
*/
|
|
68
68
|
/* Scales by 1.125 */
|
|
69
69
|
.scroller-demo-container {
|
|
70
|
-
width: 660px;
|
|
70
|
+
max-width: 660px;
|
|
71
71
|
margin: auto;
|
|
72
|
+
background: #c5dfe8;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
.step-foreground-container {
|
|
@@ -19,7 +19,8 @@ By default, `visible` will switch between `false` and `true` whenever the elemen
|
|
|
19
19
|
import { Visible } from '@reuters-graphics/graphics-components';
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
<!-- Optionally set your own `top`, `bottom`, `right` and `left` values with `px` or `%` units -->
|
|
23
|
+
<Visible top="10px">
|
|
23
24
|
{#snippet children(visible)}
|
|
24
25
|
{#if visible}
|
|
25
26
|
<p>Visible!</p>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
3
|
|
|
4
4
|
import Visible from './Visible.svelte';
|
|
5
|
+
import VisibleDemo from './demo/VisibleDemo.svelte';
|
|
5
6
|
|
|
6
7
|
const { Story } = defineMeta({
|
|
7
8
|
title: 'Components/Utilities/Visible',
|
|
@@ -9,14 +10,6 @@
|
|
|
9
10
|
});
|
|
10
11
|
</script>
|
|
11
12
|
|
|
12
|
-
<Story name="Demo"
|
|
13
|
-
<
|
|
14
|
-
{#snippet children(visible)}
|
|
15
|
-
{#if visible}
|
|
16
|
-
<p>Visible!</p>
|
|
17
|
-
{:else}
|
|
18
|
-
<p>Not yet visible.</p>
|
|
19
|
-
{/if}
|
|
20
|
-
{/snippet}
|
|
21
|
-
</Visible>
|
|
13
|
+
<Story name="Demo">
|
|
14
|
+
<VisibleDemo />
|
|
22
15
|
</Story>
|
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
* Useful for loading expensive images or other media and then keeping them around once they're first loaded.
|
|
10
10
|
*/
|
|
11
11
|
once?: boolean;
|
|
12
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `top
|
|
13
|
-
top?:
|
|
14
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `bottom
|
|
15
|
-
bottom?:
|
|
16
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `left
|
|
17
|
-
left?:
|
|
18
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `right
|
|
19
|
-
right?:
|
|
12
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `top` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
13
|
+
top?: string;
|
|
14
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `bottom` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
15
|
+
bottom?: string;
|
|
16
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `left` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
17
|
+
left?: string;
|
|
18
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `right` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
19
|
+
right?: string;
|
|
20
20
|
/** Set the Intersection Observer [threshold](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#threshold). */
|
|
21
21
|
threshold?: number;
|
|
22
22
|
children?: Snippet<[boolean]>;
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
|
|
25
25
|
let {
|
|
26
26
|
once = false,
|
|
27
|
-
top =
|
|
28
|
-
bottom =
|
|
29
|
-
left =
|
|
30
|
-
right =
|
|
27
|
+
top = '0px',
|
|
28
|
+
bottom = '0px',
|
|
29
|
+
left = '0px',
|
|
30
|
+
right = '0px',
|
|
31
31
|
threshold = 0,
|
|
32
32
|
children,
|
|
33
33
|
}: Props = $props();
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
onMount(() => {
|
|
39
39
|
if (typeof IntersectionObserver !== 'undefined') {
|
|
40
|
-
const rootMargin = `${bottom}
|
|
40
|
+
const rootMargin = `${bottom} ${left} ${top} ${right}`;
|
|
41
41
|
|
|
42
42
|
const observer = new IntersectionObserver(
|
|
43
43
|
(entries) => {
|
|
@@ -53,28 +53,18 @@
|
|
|
53
53
|
);
|
|
54
54
|
if (container) observer.observe(container);
|
|
55
55
|
return () => {
|
|
56
|
-
if (container) observer.
|
|
56
|
+
if (container) observer.unobserve(container);
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
function handler() {
|
|
60
|
-
if (container) {
|
|
61
|
-
const bcr = container.getBoundingClientRect();
|
|
62
|
-
visible =
|
|
63
|
-
bcr.bottom + bottom > 0 &&
|
|
64
|
-
bcr.right + right > 0 &&
|
|
65
|
-
bcr.top - top < window.innerHeight &&
|
|
66
|
-
bcr.left - left < window.innerWidth;
|
|
67
|
-
}
|
|
68
|
-
if (visible && once) {
|
|
69
|
-
window.removeEventListener('scroll', handler);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
window.addEventListener('scroll', handler);
|
|
73
|
-
return () => window.removeEventListener('scroll', handler);
|
|
74
59
|
});
|
|
75
60
|
</script>
|
|
76
61
|
|
|
77
|
-
<div
|
|
62
|
+
<div
|
|
63
|
+
bind:this={container}
|
|
64
|
+
class="visibility-tracker"
|
|
65
|
+
class:visible
|
|
66
|
+
class:not-visible={!visible}
|
|
67
|
+
>
|
|
78
68
|
{#if children}
|
|
79
69
|
{@render children(visible)}
|
|
80
70
|
{/if}
|
|
@@ -6,14 +6,14 @@ interface Props {
|
|
|
6
6
|
* Useful for loading expensive images or other media and then keeping them around once they're first loaded.
|
|
7
7
|
*/
|
|
8
8
|
once?: boolean;
|
|
9
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `top
|
|
10
|
-
top?:
|
|
11
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `bottom
|
|
12
|
-
bottom?:
|
|
13
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `left
|
|
14
|
-
left?:
|
|
15
|
-
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `right
|
|
16
|
-
right?:
|
|
9
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `top` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
10
|
+
top?: string;
|
|
11
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `bottom` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
12
|
+
bottom?: string;
|
|
13
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `left` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
14
|
+
left?: string;
|
|
15
|
+
/** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `right` with units. Units must be `px` or other [absolute lengths units](https://arc.net/l/quote/jkukcxqq), or `%`. */
|
|
16
|
+
right?: string;
|
|
17
17
|
/** Set the Intersection Observer [threshold](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#threshold). */
|
|
18
18
|
threshold?: number;
|
|
19
19
|
children?: Snippet<[boolean]>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Visible from '../Visible.svelte';
|
|
3
|
+
import BodyText from '../../BodyText/BodyText.svelte';
|
|
4
|
+
import Block from '../../Block/Block.svelte';
|
|
5
|
+
import FeaturePhoto from '../../FeaturePhoto/FeaturePhoto.svelte';
|
|
6
|
+
import sharkSrc from '../../FeaturePhoto/images/shark.jpg';
|
|
7
|
+
|
|
8
|
+
let top = '150px';
|
|
9
|
+
|
|
10
|
+
const demoText =
|
|
11
|
+
'Take a look at the *Elements* tab in Inspector to see how the photo in the middle of the page appears in the DOM only when its container comes into view.';
|
|
12
|
+
|
|
13
|
+
let demoText2 = $derived(
|
|
14
|
+
`The top value for \`rootMargin\` is set to \`${top}px\` in this demo. Read about how \`rootMargin\` affects the <a href='https://codepen.io/michellebarker/full/xxwLpRG'>Intersection Observer's behaviour here</a>.`
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const text =
|
|
18
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<BodyText text={`**${demoText}**`} />
|
|
22
|
+
|
|
23
|
+
<BodyText text={`**${demoText2}**`} />
|
|
24
|
+
<BodyText {text} />
|
|
25
|
+
<BodyText {text} />
|
|
26
|
+
<BodyText {text} />
|
|
27
|
+
<BodyText {text} />
|
|
28
|
+
|
|
29
|
+
<Visible {top} once={false}>
|
|
30
|
+
{#snippet children(visible)}
|
|
31
|
+
{#if visible}
|
|
32
|
+
<FeaturePhoto
|
|
33
|
+
src={sharkSrc}
|
|
34
|
+
altText="A shark!"
|
|
35
|
+
caption="Carcharodon carcharias - REUTERS"
|
|
36
|
+
/>
|
|
37
|
+
{:else}
|
|
38
|
+
<Block><h2>Not yet visible.</h2></Block>
|
|
39
|
+
{/if}
|
|
40
|
+
{/snippet}
|
|
41
|
+
</Visible>
|
|
42
|
+
<BodyText {text} />
|
|
43
|
+
<BodyText {text} />
|
|
44
|
+
<BodyText {text} />
|
|
45
|
+
<BodyText {text} />
|
|
46
|
+
<BodyText {text} />
|
package/dist/globals.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { default as FeaturePhoto } from './components/FeaturePhoto/FeaturePhoto.
|
|
|
14
14
|
export { default as Framer } from './components/Framer/Framer.svelte';
|
|
15
15
|
export { default as GraphicBlock } from './components/GraphicBlock/GraphicBlock.svelte';
|
|
16
16
|
export { default as Headline } from './components/Headline/Headline.svelte';
|
|
17
|
+
export { default as Headpile } from './components/Headpile/Headpile.svelte';
|
|
17
18
|
export { default as HeroHeadline } from './components/HeroHeadline/HeroHeadline.svelte';
|
|
18
19
|
export { default as EndNotes } from './components/EndNotes/EndNotes.svelte';
|
|
19
20
|
export { default as InfoBox } from './components/InfoBox/InfoBox.svelte';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export { default as FeaturePhoto } from './components/FeaturePhoto/FeaturePhoto.
|
|
|
16
16
|
export { default as Framer } from './components/Framer/Framer.svelte';
|
|
17
17
|
export { default as GraphicBlock } from './components/GraphicBlock/GraphicBlock.svelte';
|
|
18
18
|
export { default as Headline } from './components/Headline/Headline.svelte';
|
|
19
|
+
export { default as Headpile } from './components/Headpile/Headpile.svelte';
|
|
19
20
|
export { default as HeroHeadline } from './components/HeroHeadline/HeroHeadline.svelte';
|
|
20
21
|
export { default as EndNotes } from './components/EndNotes/EndNotes.svelte';
|
|
21
22
|
export { default as InfoBox } from './components/InfoBox/InfoBox.svelte';
|
package/package.json
CHANGED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const SITE_ID = 'reuters.com';
|
|
2
|
-
const attachScript = () => {
|
|
3
|
-
const b = document.body;
|
|
4
|
-
const e = document.createElement('script');
|
|
5
|
-
e.id = 'parsely-cfg';
|
|
6
|
-
e.src = `//cdn.parsely.com/keys/${SITE_ID}/p.js`;
|
|
7
|
-
e.setAttribute('async', '');
|
|
8
|
-
e.setAttribute('defer', '');
|
|
9
|
-
b.appendChild(e);
|
|
10
|
-
};
|
|
11
|
-
export default () => {
|
|
12
|
-
window.PARSELY = window.PARSELY || {
|
|
13
|
-
autotrack: false,
|
|
14
|
-
onReady() {
|
|
15
|
-
window.PARSELY.updateDefaults({
|
|
16
|
-
data: {
|
|
17
|
-
is_logged_in: false,
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
window.PARSELY.beacon.trackPageView();
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
attachScript();
|
|
24
|
-
};
|
|
25
|
-
export const registerPageview = () => {
|
|
26
|
-
if (typeof window === 'undefined' || !window.PARSELY)
|
|
27
|
-
return;
|
|
28
|
-
window.PARSELY.beacon.trackPageView();
|
|
29
|
-
};
|