Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions components/src/Scroller/Scroller.stories.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script module>
import { defineMeta } from '@storybook/addon-svelte-csf';
import { expect } from 'storybook/test';
import { expect, fn } from 'storybook/test';

import Scroller from './Scroller.svelte';

Expand All @@ -23,7 +23,7 @@
<Story
name="Default"
asChild
play={async ({ step, canvasElement }) => {
play={async ({ step, canvasElement, userEvent }) => {
await step('Verify state values are set', async () => {
expect(index).toBeGreaterThanOrEqual(0);
expect(offset).toBeGreaterThanOrEqual(0);
Expand Down Expand Up @@ -74,6 +74,7 @@
<p><code>index</code> / {index}</p>
<p><code>offset</code> / {offset}</p>
<p><code>progress</code> / {progress}</p>
<button>I'm not clickable</button>
{/snippet}

{#snippet foreground()}
Expand All @@ -87,6 +88,40 @@
</div>
</Story>

<Story
name="Enable background events"
asChild
play={async ({ step, canvasElement, userEvent }) => {
await step('Background button fires click event', async () => {
const handler = fn();
const button = canvasElement.querySelector('button');
expect(button).toBeDefined();
if (button) {
button.addEventListener('click', handler);
await userEvent.click(button);
expect(handler).toHaveBeenCalled();
}
});
}}
>
<div>
<Scroller interactive="background">
{#snippet background()}
<p>
This is the background content. It will stay fixed in place while the foreground scrolls
over the top.
</p>
<button>I'm clickable</button>
{/snippet}

{#snippet foreground()}
<section>This is the first section.</section>
<section>This is the second section.</section>
{/snippet}
</Scroller>
</div>
</Story>

<style>
section {
height: 25vh;
Expand Down
21 changes: 15 additions & 6 deletions components/src/Scroller/Scroller.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script module lang="ts">
import { type Snippet } from 'svelte';
interface ScrollHandler {
(): void;
}
Expand Down Expand Up @@ -166,19 +167,22 @@
* Whether the scroller is currently visible in the viewport (bindable)
*/
visible?: boolean;

/**
* Whether background and/or foreground elements trigger mouse events
*/
interactive?: 'background' | 'foreground' | 'both' | 'none';
}

let {
// Configuration props (read-only)
foreground = null,
background = null,
top = 0,
bottom = 1,
threshold = 0.5,
query = 'section',
parallax = false,

// Binding props (two-way binding)
interactive = 'foreground',
index = $bindable(0),
count = $bindable(0),
offset = $bindable(0),
Expand Down Expand Up @@ -290,13 +294,19 @@
<svelte:window bind:innerHeight={windowHeight} />

<svelte-scroller-outer bind:this={outerWrapper}>
<svelte-scroller-background-container class="background-container">
<svelte-scroller-background-container
class="background-container"
style:pointer-events={['background', 'both'].includes(interactive) ? 'all' : 'none'}
>
<svelte-scroller-background bind:this={backgroundWrapper} style={backgroundStyle}>
{@render background()}
</svelte-scroller-background>
</svelte-scroller-background-container>

<svelte-scroller-foreground bind:this={foregroundWrapper}>
<svelte-scroller-foreground
bind:this={foregroundWrapper}
style:pointer-events={['foreground', 'both'].includes(interactive) ? 'all' : 'none'}
>
{@render foreground()}
</svelte-scroller-foreground>
</svelte-scroller-outer>
Expand Down Expand Up @@ -333,7 +343,6 @@
width: 100%;
height: 100%;
max-width: 100%;
pointer-events: none;
will-change: transform;
}
</style>
Loading