diff --git a/.changeset/khaki-points-pull.md b/.changeset/khaki-points-pull.md
new file mode 100644
index 00000000..6430b362
--- /dev/null
+++ b/.changeset/khaki-points-pull.md
@@ -0,0 +1,5 @@
+---
+'@reuters-graphics/graphics-components': patch
+---
+
+Creates ScrollerBase component, which is used in Scroller and can be used to make custom scrollytelling components.
diff --git a/src/components/Scroller/Background.svelte b/src/components/Scroller/Background.svelte
index 337a3c15..6762b6bd 100644
--- a/src/components/Scroller/Background.svelte
+++ b/src/components/Scroller/Background.svelte
@@ -9,16 +9,25 @@
}
let { index, steps, preload = 1, stackBackground = true }: Props = $props();
+
+ function showStep(i: number) {
+ if (preload === 0) return true;
+ if (stackBackground) return i >= 0;
+ return i >= index - preload && i <= index + preload;
+ }
+
+ function isVisible(i: number) {
+ if (stackBackground) return i <= index;
+ return i === index;
+ }
{#each steps as step, i}
-
-
- {#if preload === 0 || (i >= (stackBackground ? 0 : index - preload) && i <= index + preload)}
+ {#if showStep(i)}
index : i !== index}
+ class={`step step-${i + 1} w-full absolute`}
+ class:visible={isVisible(i)}
+ class:invisible={!isVisible(i)}
>
diff --git a/src/components/Scroller/Scroller.mdx b/src/components/Scroller/Scroller.mdx
index 31c9de51..54994565 100644
--- a/src/components/Scroller/Scroller.mdx
+++ b/src/components/Scroller/Scroller.mdx
@@ -8,7 +8,7 @@ import * as ScrollerStories from './Scroller.stories.svelte';
The `Scroller` component creates a basic scrollytelling graphic with layout options.
-> This component is designed to handle most common layouts for scrollytelling. To make something more complex, customise [ScrollerBase](https://github.com/reuters-graphics/graphics-components/blob/main/src/components/Scroller/ScrollerBase/index.svelte), which is a Svelte 5 version of the [svelte-scroller](https://github.com/sveltejs/svelte-scroller).
+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).
[Demo](?path=/story/components-graphics-scroller--demo)
diff --git a/src/components/Scroller/Scroller.svelte b/src/components/Scroller/Scroller.svelte
index b6c897b2..37415fa1 100644
--- a/src/components/Scroller/Scroller.svelte
+++ b/src/components/Scroller/Scroller.svelte
@@ -1,6 +1,6 @@
+
+
+ {#snippet backgroundSnippet()}
+
+
+ Current step: {index + 1}/{count}
+
+
+
+ Offset in current step
+
+
+ Total progress
+
+ {/snippet}
+ {#snippet foregroundSnippet()}
+
+ Step 1
+ Step 2
+ Step 3
+ Step 4
+ Step 5
+ {/snippet}
+
+
+
+```
diff --git a/src/components/ScrollerBase/ScrollerBase.stories.svelte b/src/components/ScrollerBase/ScrollerBase.stories.svelte
new file mode 100644
index 00000000..e8cbb78a
--- /dev/null
+++ b/src/components/ScrollerBase/ScrollerBase.stories.svelte
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/components/Scroller/ScrollerBase/index.svelte b/src/components/ScrollerBase/ScrollerBase.svelte
similarity index 99%
rename from src/components/Scroller/ScrollerBase/index.svelte
rename to src/components/ScrollerBase/ScrollerBase.svelte
index 807f05ff..21c2d9f9 100644
--- a/src/components/Scroller/ScrollerBase/index.svelte
+++ b/src/components/ScrollerBase/ScrollerBase.svelte
@@ -117,7 +117,7 @@
top = 0,
bottom = 1,
threshold = 0.5,
- query = 'section',
+ query = 'div.step-foreground-container',
parallax = false,
backgroundSnippet,
foregroundSnippet,
diff --git a/src/components/ScrollerBase/demo/DraggableLabel.svelte b/src/components/ScrollerBase/demo/DraggableLabel.svelte
new file mode 100644
index 00000000..34e7cd8c
--- /dev/null
+++ b/src/components/ScrollerBase/demo/DraggableLabel.svelte
@@ -0,0 +1,95 @@
+
+
+ {
+ const customEvent = event as unknown as { detail: { value: number } };
+ value = customEvent.detail.value;
+ }}
+ role="slider"
+ aria-valuemin="0"
+ aria-valuemax="1"
+ aria-valuenow={value}
+ tabindex="0"
+>
+
+
+
{label}: {round(value)}
+
+
+
diff --git a/src/components/ScrollerBase/demo/ScrollerDemo.svelte b/src/components/ScrollerBase/demo/ScrollerDemo.svelte
new file mode 100644
index 00000000..34f4383c
--- /dev/null
+++ b/src/components/ScrollerBase/demo/ScrollerDemo.svelte
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/index.ts b/src/index.ts
index f5c4197d..93f06e4f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -40,6 +40,7 @@ export { default as SiteFooter } from './components/SiteFooter/SiteFooter.svelte
export { default as SiteHeader } from './components/SiteHeader/SiteHeader.svelte';
export { default as SiteHeadline } from './components/SiteHeadline/SiteHeadline.svelte';
export { default as Spinner } from './components/Spinner/Spinner.svelte';
+export { default as ScrollerBase } from './components/ScrollerBase/ScrollerBase.svelte';
export { default as SponsorshipAd } from './components/AdSlot/SponsorshipAd.svelte';
export { default as Table } from './components/Table/Table.svelte';
export { default as Theme, themes } from './components/Theme/Theme.svelte';