@reuters-graphics/graphics-components 3.0.4 → 3.0.6
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/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/Scroller/Background.svelte +15 -6
- package/dist/components/Scroller/Scroller.mdx +1 -1
- package/dist/components/Scroller/Scroller.svelte +1 -1
- package/dist/components/ScrollerBase/ScrollerBase.mdx +82 -0
- package/dist/components/ScrollerBase/ScrollerBase.stories.svelte +12 -0
- package/dist/components/ScrollerBase/ScrollerBase.stories.svelte.d.ts +19 -0
- package/dist/components/{Scroller/ScrollerBase/index.svelte → ScrollerBase/ScrollerBase.svelte} +2 -2
- package/dist/components/{Scroller/ScrollerBase/index.svelte.d.ts → ScrollerBase/ScrollerBase.svelte.d.ts} +3 -3
- package/dist/components/ScrollerBase/demo/DraggableLabel.svelte +96 -0
- package/dist/components/ScrollerBase/demo/DraggableLabel.svelte.d.ts +21 -0
- package/dist/components/ScrollerBase/demo/ScrollerDemo.svelte +83 -0
- package/dist/components/ScrollerBase/demo/ScrollerDemo.svelte.d.ts +3 -0
- package/dist/components/Theme/@types/component.d.ts +1 -0
- package/dist/components/Theme/Theme.svelte +2 -2
- package/dist/components/Theme/Theme.svelte.d.ts +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +1 -1
|
@@ -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
|
|
@@ -9,16 +9,25 @@
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
let { index, steps, preload = 1, stackBackground = true }: Props = $props();
|
|
12
|
+
|
|
13
|
+
function showStep(i: number) {
|
|
14
|
+
if (preload === 0) return true;
|
|
15
|
+
if (stackBackground) return i >= 0;
|
|
16
|
+
return i >= index - preload && i <= index + preload;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isVisible(i: number) {
|
|
20
|
+
if (stackBackground) return i <= index;
|
|
21
|
+
return i === index;
|
|
22
|
+
}
|
|
12
23
|
</script>
|
|
13
24
|
|
|
14
25
|
{#each steps as step, i}
|
|
15
|
-
|
|
16
|
-
<!-- Unless stackBackground is true. If so, keep all steps before the current one loaded. -->
|
|
17
|
-
{#if preload === 0 || (i >= (stackBackground ? 0 : index - preload) && i <= index + preload)}
|
|
26
|
+
{#if showStep(i)}
|
|
18
27
|
<div
|
|
19
|
-
class=
|
|
20
|
-
class:visible={
|
|
21
|
-
class:invisible={
|
|
28
|
+
class={`step step-${i + 1} w-full absolute`}
|
|
29
|
+
class:visible={isVisible(i)}
|
|
30
|
+
class:invisible={!isVisible(i)}
|
|
22
31
|
>
|
|
23
32
|
<step.background {...step.backgroundProps || {}}></step.background>
|
|
24
33
|
</div>
|
|
@@ -8,7 +8,7 @@ import * as ScrollerStories from './Scroller.stories.svelte';
|
|
|
8
8
|
|
|
9
9
|
The `Scroller` component creates a basic scrollytelling graphic with layout options.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
This component is designed to handle most common layouts for scrollytelling. To make something more complex, customise [ScrollerBase](?path=/story/components-graphics-scrollerbase--docs), which is a Svelte 5 version of the [svelte-scroller](https://github.com/sveltejs/svelte-scroller).
|
|
12
12
|
|
|
13
13
|
[Demo](?path=/story/components-graphics-scroller--demo)
|
|
14
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- @component `Scroller` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-graphics-scroller--docs) -->
|
|
2
2
|
<script lang="ts">
|
|
3
|
-
import ScrollerBase from '
|
|
3
|
+
import ScrollerBase from '../ScrollerBase/ScrollerBase.svelte';
|
|
4
4
|
import Background from './Background.svelte';
|
|
5
5
|
import Foreground from './Foreground.svelte';
|
|
6
6
|
import Embedded from './Embedded/index.svelte';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import * as ScrollerBaseStories from './ScrollerBase.stories.svelte';
|
|
4
|
+
|
|
5
|
+
<Meta of={ScrollerBaseStories} />
|
|
6
|
+
|
|
7
|
+
# ScrollerBase
|
|
8
|
+
|
|
9
|
+
The `ScrollerBase` component powers the [`Scroller` component](?path=/story/components-graphics-scroller--docs), which creates a basic storytelling graphic with preset layout options. `ScrollerBase` contains the bare minimum code necessary for a scrollytelling section, and allows for customisation beyond what the [`Scroller` component](?path=/story/components-graphics-scroller--docs) allows.
|
|
10
|
+
|
|
11
|
+
`ScrollerBase` is a Svelte 5 version of the [svelte-scroller](https://github.com/sveltejs/svelte-scroller).
|
|
12
|
+
|
|
13
|
+
> **Important❗:** Make sure the HTML element containing each foreground is a div with the class `step-foreground-container`. If you're modifying this to something else, pass the appropriate selector to the `query` prop.
|
|
14
|
+
|
|
15
|
+
[Demo](?path=/story/components-graphics-scrollerbase--demo)
|
|
16
|
+
|
|
17
|
+
```svelte
|
|
18
|
+
<script lang="ts">
|
|
19
|
+
import { ScrollerBase } from '@reuters-graphics/graphics-components';
|
|
20
|
+
|
|
21
|
+
// Optional: Bind your own variables to use them in your code.
|
|
22
|
+
let count = $state(1);
|
|
23
|
+
let index = $state(0);
|
|
24
|
+
let offset = $state(0);
|
|
25
|
+
let progress = $state(0);
|
|
26
|
+
let top = $state(0.1);
|
|
27
|
+
let threshold = $state(0.5);
|
|
28
|
+
let bottom = $state(0.9);
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<ScrollerBase
|
|
32
|
+
{top}
|
|
33
|
+
{threshold}
|
|
34
|
+
{bottom}
|
|
35
|
+
bind:count
|
|
36
|
+
bind:index
|
|
37
|
+
bind:offset
|
|
38
|
+
bind:progress
|
|
39
|
+
query="div.step-foreground-container"
|
|
40
|
+
>
|
|
41
|
+
{#snippet backgroundSnippet()}
|
|
42
|
+
<!-- Add custom background HTML or component -->
|
|
43
|
+
<p class="mb-0">
|
|
44
|
+
Current step: <strong>{index + 1}/{count}</strong>
|
|
45
|
+
</p>
|
|
46
|
+
<progress class="mb-4" value={(index + 1) / count}></progress>
|
|
47
|
+
|
|
48
|
+
<p class="mb-0">Offset in current step</p>
|
|
49
|
+
<progress class="mb-4" value={offset}></progress>
|
|
50
|
+
|
|
51
|
+
<p class="mb-0">Total progress</p>
|
|
52
|
+
<progress class="mb-4" value={progress}></progress>
|
|
53
|
+
{/snippet}
|
|
54
|
+
{#snippet foregroundSnippet()}
|
|
55
|
+
<!-- Add custom foreground HTML or component -->
|
|
56
|
+
<div class="step-foreground-container">Step 1</div>
|
|
57
|
+
<div class="step-foreground-container">Step 2</div>
|
|
58
|
+
<div class="step-foreground-container">Step 3</div>
|
|
59
|
+
<div class="step-foreground-container">Step 4</div>
|
|
60
|
+
<div class="step-foreground-container">Step 5</div>
|
|
61
|
+
{/snippet}
|
|
62
|
+
</ScrollerBase>
|
|
63
|
+
|
|
64
|
+
<style lang="scss">
|
|
65
|
+
@use '@reuters-graphics/graphics-components/dist/scss/mixins' as mixins;
|
|
66
|
+
|
|
67
|
+
.scroller-demo-container {
|
|
68
|
+
width: mixins.$column-width-normal;
|
|
69
|
+
margin: auto;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.step-foreground-container {
|
|
73
|
+
height: 100vh;
|
|
74
|
+
width: 50%;
|
|
75
|
+
background-color: rgba(0, 0, 0, 0.2);
|
|
76
|
+
padding: 1em;
|
|
77
|
+
margin: 0 0 2em 0;
|
|
78
|
+
position: relative;
|
|
79
|
+
left: 50%;
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
82
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import ScrollerBase from './ScrollerBase.svelte';
|
|
4
|
+
import ScrollerDemo from './demo/ScrollerDemo.svelte';
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: 'Components/Graphics/ScrollerBase',
|
|
8
|
+
component: ScrollerBase,
|
|
9
|
+
});
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Story name="Demo"><ScrollerDemo /></Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ScrollerBase from './ScrollerBase.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 ScrollerBase: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type ScrollerBase = InstanceType<typeof ScrollerBase>;
|
|
19
|
+
export default ScrollerBase;
|
package/dist/components/{Scroller/ScrollerBase/index.svelte → ScrollerBase/ScrollerBase.svelte}
RENAMED
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
top = 0,
|
|
118
118
|
bottom = 1,
|
|
119
119
|
threshold = 0.5,
|
|
120
|
-
query = '
|
|
120
|
+
query = 'div.step-foreground-container',
|
|
121
121
|
parallax = false,
|
|
122
122
|
backgroundSnippet,
|
|
123
123
|
foregroundSnippet,
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
let wh = $state(0);
|
|
134
134
|
let fixed = $state(false);
|
|
135
135
|
let offset_top = 0;
|
|
136
|
-
let width = 1;
|
|
136
|
+
let width = $state(1);
|
|
137
137
|
|
|
138
138
|
let top_px = $derived(Math.round(top * wh));
|
|
139
139
|
let bottom_px = $derived(Math.round(bottom * wh));
|
|
@@ -27,6 +27,6 @@ interface Props {
|
|
|
27
27
|
/** Whether the foreground is visible */
|
|
28
28
|
visible?: boolean;
|
|
29
29
|
}
|
|
30
|
-
declare const
|
|
31
|
-
type
|
|
32
|
-
export default
|
|
30
|
+
declare const ScrollerBase: import("svelte").Component<Props, {}, "progress" | "offset" | "index" | "count" | "visible">;
|
|
31
|
+
type ScrollerBase = ReturnType<typeof ScrollerBase>;
|
|
32
|
+
export default ScrollerBase;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let value = 0;
|
|
3
|
+
export let label = 'label';
|
|
4
|
+
|
|
5
|
+
function drag(node: HTMLElement) {
|
|
6
|
+
function handleMousedown() {
|
|
7
|
+
function handleMousemove(event: MouseEvent) {
|
|
8
|
+
event.preventDefault();
|
|
9
|
+
|
|
10
|
+
node.dispatchEvent(
|
|
11
|
+
new CustomEvent('drag', {
|
|
12
|
+
detail: {
|
|
13
|
+
value: event.clientY / window.innerHeight,
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function handleMouseup() {
|
|
20
|
+
window.removeEventListener('mousemove', handleMousemove);
|
|
21
|
+
window.removeEventListener('mouseup', handleMouseup);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
window.addEventListener('mousemove', handleMousemove);
|
|
25
|
+
window.addEventListener('mouseup', handleMouseup);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
node.addEventListener('mousedown', handleMousedown);
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
destroy() {
|
|
32
|
+
node.removeEventListener('mousedown', handleMousedown);
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Round to 2 decimal places
|
|
38
|
+
function round(value: number): number {
|
|
39
|
+
return Math.round(value * 100) / 100;
|
|
40
|
+
}
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<div
|
|
44
|
+
class="label"
|
|
45
|
+
style="top: {value * 100}%"
|
|
46
|
+
use:drag
|
|
47
|
+
ondrag={(event: DragEvent) => {
|
|
48
|
+
const customEvent = event as unknown as { detail: { value: number } };
|
|
49
|
+
value = customEvent.detail.value;
|
|
50
|
+
}}
|
|
51
|
+
role="slider"
|
|
52
|
+
aria-valuemin="0"
|
|
53
|
+
aria-valuemax="1"
|
|
54
|
+
aria-valuenow={value}
|
|
55
|
+
tabindex="0"
|
|
56
|
+
>
|
|
57
|
+
<div class="drag-target"></div>
|
|
58
|
+
<hr />
|
|
59
|
+
<p>{label}: {round(value)}</p>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<style>/* Generated from
|
|
63
|
+
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
|
|
64
|
+
*/
|
|
65
|
+
/* Generated from
|
|
66
|
+
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
|
|
67
|
+
*/
|
|
68
|
+
/* Scales by 1.125 */
|
|
69
|
+
.label {
|
|
70
|
+
position: fixed;
|
|
71
|
+
top: 0;
|
|
72
|
+
right: 0;
|
|
73
|
+
width: 150px;
|
|
74
|
+
height: 0;
|
|
75
|
+
cursor: ns-resize;
|
|
76
|
+
}
|
|
77
|
+
.label .drag-target {
|
|
78
|
+
position: absolute;
|
|
79
|
+
height: 20px;
|
|
80
|
+
top: -10px;
|
|
81
|
+
}
|
|
82
|
+
.label hr {
|
|
83
|
+
position: absolute;
|
|
84
|
+
top: 0;
|
|
85
|
+
width: 100%;
|
|
86
|
+
height: 2px;
|
|
87
|
+
background: red;
|
|
88
|
+
border: none;
|
|
89
|
+
margin: 0;
|
|
90
|
+
}
|
|
91
|
+
.label p {
|
|
92
|
+
position: absolute;
|
|
93
|
+
font-family: var(--theme-font-family-sans-serif);
|
|
94
|
+
font-weight: 500;
|
|
95
|
+
font-size: var(--theme-font-size-sm);
|
|
96
|
+
}</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
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> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const DraggableLabel: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
value?: number;
|
|
16
|
+
label?: string;
|
|
17
|
+
}, {
|
|
18
|
+
[evt: string]: CustomEvent<any>;
|
|
19
|
+
}, {}, {}, string>;
|
|
20
|
+
type DraggableLabel = InstanceType<typeof DraggableLabel>;
|
|
21
|
+
export default DraggableLabel;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ScrollerBase from '../ScrollerBase.svelte';
|
|
3
|
+
import DraggableLabel from './DraggableLabel.svelte';
|
|
4
|
+
import BodyText from '../../BodyText/BodyText.svelte';
|
|
5
|
+
|
|
6
|
+
let count = $state(1);
|
|
7
|
+
let index = $state(0);
|
|
8
|
+
let offset = $state(0);
|
|
9
|
+
let progress = $state(0);
|
|
10
|
+
let top = $state(0.1);
|
|
11
|
+
let threshold = $state(0.5);
|
|
12
|
+
let bottom = $state(0.9);
|
|
13
|
+
|
|
14
|
+
const text =
|
|
15
|
+
'Read the documentation on the props `progress`, `top`, `threshold`, `bottom` under **Controls** to understand how they work. \n\nAdjust the red sliders on the right to see how changes in these values affect scrolling behaviour.';
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<BodyText {text} />
|
|
19
|
+
|
|
20
|
+
<div class="scroller-demo-container">
|
|
21
|
+
<ScrollerBase
|
|
22
|
+
{top}
|
|
23
|
+
{threshold}
|
|
24
|
+
{bottom}
|
|
25
|
+
bind:count
|
|
26
|
+
bind:index
|
|
27
|
+
bind:offset
|
|
28
|
+
bind:progress
|
|
29
|
+
query="div.step-foreground-container"
|
|
30
|
+
>
|
|
31
|
+
{#snippet backgroundSnippet()}
|
|
32
|
+
<p class="mb-0">
|
|
33
|
+
Current step: <strong>{index + 1}/{count}</strong>
|
|
34
|
+
</p>
|
|
35
|
+
<progress class="mb-4" value={(index + 1) / count}></progress>
|
|
36
|
+
|
|
37
|
+
<p class="mb-0">Offset in current step</p>
|
|
38
|
+
<progress class="mb-4" value={offset}></progress>
|
|
39
|
+
|
|
40
|
+
<p class="mb-0">Total progress</p>
|
|
41
|
+
<progress class="mb-4" value={progress}></progress>
|
|
42
|
+
{/snippet}
|
|
43
|
+
{#snippet foregroundSnippet()}
|
|
44
|
+
<div class="step-foreground-container font-medium">Step 1</div>
|
|
45
|
+
<div class="step-foreground-container font-medium">Step 2</div>
|
|
46
|
+
<div class="step-foreground-container font-medium">Step 3</div>
|
|
47
|
+
<div class="step-foreground-container font-medium">Step 4</div>
|
|
48
|
+
<div class="step-foreground-container font-medium">Step 5</div>
|
|
49
|
+
{/snippet}
|
|
50
|
+
</ScrollerBase>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<BodyText
|
|
54
|
+
text="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.
|
|
55
|
+
"
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
<DraggableLabel bind:value={top} label="top" />
|
|
59
|
+
<DraggableLabel bind:value={threshold} label="threshold" />
|
|
60
|
+
<DraggableLabel bind:value={bottom} label="bottom" />
|
|
61
|
+
|
|
62
|
+
<style>/* Generated from
|
|
63
|
+
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
|
|
64
|
+
*/
|
|
65
|
+
/* Generated from
|
|
66
|
+
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
|
|
67
|
+
*/
|
|
68
|
+
/* Scales by 1.125 */
|
|
69
|
+
.scroller-demo-container {
|
|
70
|
+
max-width: 660px;
|
|
71
|
+
margin: auto;
|
|
72
|
+
background: #c5dfe8;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.step-foreground-container {
|
|
76
|
+
height: 100vh;
|
|
77
|
+
width: 50%;
|
|
78
|
+
background-color: rgba(0, 0, 0, 0.2);
|
|
79
|
+
padding: 1em;
|
|
80
|
+
margin: 0 0 2em 0;
|
|
81
|
+
position: relative;
|
|
82
|
+
left: 50%;
|
|
83
|
+
}</style>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import mergeThemes from './utils/merge.js';
|
|
15
15
|
|
|
16
16
|
// Types
|
|
17
|
-
import type { CustomTheme } from './@types/component';
|
|
17
|
+
import type { CustomTheme, Theme } from './@types/component';
|
|
18
18
|
import type { Snippet } from 'svelte';
|
|
19
19
|
type Base = 'light' | 'dark';
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
/** Custom theme object. Can be a partial theme with just
|
|
23
23
|
* what you want to change.
|
|
24
24
|
*/
|
|
25
|
-
theme?: CustomTheme;
|
|
25
|
+
theme?: CustomTheme | Theme;
|
|
26
26
|
/**
|
|
27
27
|
* Base theme is one of `light` or `dark` and will be merged
|
|
28
28
|
* with your custom theme to fill in any values you don't
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
* Pre-made themes you can import.
|
|
3
3
|
*/
|
|
4
4
|
export declare const themes: {
|
|
5
|
-
light:
|
|
6
|
-
dark:
|
|
5
|
+
light: Theme;
|
|
6
|
+
dark: Theme;
|
|
7
7
|
};
|
|
8
|
-
import type { CustomTheme } from './@types/component';
|
|
8
|
+
import type { CustomTheme, Theme } from './@types/component';
|
|
9
9
|
import type { Snippet } from 'svelte';
|
|
10
10
|
type Base = 'light' | 'dark';
|
|
11
11
|
interface Props {
|
|
12
12
|
/** Custom theme object. Can be a partial theme with just
|
|
13
13
|
* what you want to change.
|
|
14
14
|
*/
|
|
15
|
-
theme?: CustomTheme;
|
|
15
|
+
theme?: CustomTheme | Theme;
|
|
16
16
|
/**
|
|
17
17
|
* Base theme is one of `light` or `dark` and will be merged
|
|
18
18
|
* with your custom theme to fill in any values you don't
|
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';
|
|
@@ -34,6 +35,7 @@ export { default as SiteFooter } from './components/SiteFooter/SiteFooter.svelte
|
|
|
34
35
|
export { default as SiteHeader } from './components/SiteHeader/SiteHeader.svelte';
|
|
35
36
|
export { default as SiteHeadline } from './components/SiteHeadline/SiteHeadline.svelte';
|
|
36
37
|
export { default as Spinner } from './components/Spinner/Spinner.svelte';
|
|
38
|
+
export { default as ScrollerBase } from './components/ScrollerBase/ScrollerBase.svelte';
|
|
37
39
|
export { default as SponsorshipAd } from './components/AdSlot/SponsorshipAd.svelte';
|
|
38
40
|
export { default as Table } from './components/Table/Table.svelte';
|
|
39
41
|
export { default as Theme, themes } from './components/Theme/Theme.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';
|
|
@@ -36,6 +37,7 @@ export { default as SiteFooter } from './components/SiteFooter/SiteFooter.svelte
|
|
|
36
37
|
export { default as SiteHeader } from './components/SiteHeader/SiteHeader.svelte';
|
|
37
38
|
export { default as SiteHeadline } from './components/SiteHeadline/SiteHeadline.svelte';
|
|
38
39
|
export { default as Spinner } from './components/Spinner/Spinner.svelte';
|
|
40
|
+
export { default as ScrollerBase } from './components/ScrollerBase/ScrollerBase.svelte';
|
|
39
41
|
export { default as SponsorshipAd } from './components/AdSlot/SponsorshipAd.svelte';
|
|
40
42
|
export { default as Table } from './components/Table/Table.svelte';
|
|
41
43
|
export { default as Theme, themes } from './components/Theme/Theme.svelte';
|