Skip to content

Commit

Permalink
fix: IntersectionObserverShared once now works
Browse files Browse the repository at this point in the history
  • Loading branch information
jacob-8 committed Jan 3, 2024
1 parent 28a4a3b commit 85b249c
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 74 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"@types/youtube": "^0.0.47",
"@unocss/svelte-scoped": "^0.55.7",
"bumpp": "^9.2.0",
"kitbook": "1.0.0-beta.4",
"kitbook": "1.0.0-beta.11",
"publint": "^0.2.2",
"svelte": "^4.2.0",
"svelte-check": "^3.5.1",
Expand Down
26 changes: 13 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions src/lib/functions/IntersectionObserver.composition
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script context="module" lang="ts">
// import type { Viewport } from 'kitbook'
// override default full-width composition viewport (set width as null for it to be auto-adjusting full-width)
// export const viewports: Viewport[] = [
// { width: 600, height: 400 },
// ]
// at the moment only the first viewport will be shown - updates are coming to show all viewports
</script>

<script lang="ts">
import IntersectionObserver from './IntersectionObserver.svelte'
</script>

<IntersectionObserver let:intersecting>
<div>
{intersecting}
</div>
</IntersectionObserver>
34 changes: 0 additions & 34 deletions src/lib/functions/IntersectionObserver.md
Original file line number Diff line number Diff line change
@@ -1,35 +1 @@
<script lang="ts">
import IntersectionObserver from './IntersectionObserver.svelte';
import IntersectionObserverShared from './IntersectionObserverShared.svelte';
import { Story } from 'kitbook';
</script>

# Intersection Observer

Observes the first child element placed inside.

<Story name="single Use">
<IntersectionObserver let:intersecting>
<div>
{intersecting}
</div>
</IntersectionObserver>
</Story>

Can be used to watch many items, efficiently. Note that the first element to init's `top`, `right`, `bottom`, `left` and `threshold` values will be used. We use -150 on the bottom here so you can see the observer working without needing dev tools.

<Story name="shared use">
{#each Array(3) as _}
<IntersectionObserverShared let:intersecting bottom={-150}>
<div class:intersecting style="height: 500px;">
{intersecting}
</div>
</IntersectionObserverShared>
{/each}
</Story>

<style>
.intersecting {
--at-apply: bg-red-100 border border-red-400;
}
</style>
22 changes: 22 additions & 0 deletions src/lib/functions/IntersectionObserverShared.composition
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script context="module" lang="ts">
import type { Viewport } from "kitbook";
export const viewports: Viewport[] = [{ width: 600, height: 600 }];
</script>

<script lang="ts">
import IntersectionObserverShared from "./IntersectionObserverShared.svelte";
</script>

{#each Array(10) as _}
<IntersectionObserverShared once let:intersecting top={-150} bottom={-150}>
<div class:intersecting style="height: 100px;">
{intersecting}
</div>
</IntersectionObserverShared>
{/each}

<style>
.intersecting {
--at-apply: bg-red-100 border border-red-400;
}
</style>
3 changes: 3 additions & 0 deletions src/lib/functions/IntersectionObserverShared.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Can be used to watch many items, efficiently. Note that the first element to init's `top`, `right`, `bottom`, `left` and `threshold` values will be used. We use -150 on the bottom and top here so you can see the observer working without needing dev tools.

In this demo we are using `once` to unobserve once an element comes into view.
35 changes: 20 additions & 15 deletions src/lib/functions/IntersectionObserverShared.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</script>

<script lang="ts">
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
import { onMount, onDestroy, createEventDispatcher } from "svelte";
/**
* Set to `true` to unobserve the element after it intersects the viewport.
Expand All @@ -41,13 +41,16 @@
onMount(() => {
childElement = container.firstElementChild as HTMLElement;
if (!childElement) {
return console.error('IntersectionObserver: No child element found')
return console.error("IntersectionObserver: No child element found");
}
if (typeof IntersectionObserver !== 'undefined') {
if (typeof IntersectionObserver !== "undefined") {
if (!observer) {
let isIframe = window !== window.parent;
let root = isIframe ? window.document : null; // Use the iframe's document as root if in an iframe
const rootMargin = `${top}px ${right}px ${bottom}px ${left}px`;
console.log({rootMargin})
console.log({ rootMargin });
observer = new IntersectionObserver(
(entries) => {
Expand All @@ -57,15 +60,19 @@
}
},
{
root,
rootMargin,
threshold,
}
},
);
}
add(childElement, (isIntersecting: boolean) => {
const fired_when_interesecting_changes = (isIntersecting: boolean) => {
if (once && isIntersecting) remove(childElement);
dispatch('intersected');
intersecting = isIntersecting;
});
};
add(childElement, fired_when_interesecting_changes);
return () => remove(container);
}
Expand All @@ -79,27 +86,25 @@
bcr.left - left < window.innerWidth;
if (intersecting && once) {
window.removeEventListener('scroll', handler);
window.removeEventListener("scroll", handler);
}
}
window.addEventListener('scroll', handler);
return () => window.removeEventListener('scroll', handler);
window.addEventListener("scroll", handler);
return () => window.removeEventListener("scroll", handler);
});
const dispatch = createEventDispatcher<{ intersected: null; hidden: null }>();
$: if (intersecting === true) {
once && remove(container);
dispatch('intersected');
if (intervalMs) {
interval = setInterval(() => {
if (intersecting === true) {
dispatch('intersected');
dispatch("intersected");
}
}, intervalMs);
}
} else {
dispatch('hidden');
dispatch("hidden");
}
onDestroy(() => {
Expand All @@ -114,4 +119,4 @@
<!-- Tips from:
https://svelte.dev/repl/c461dfe7dbf84998a03fdb30785c27f3?version=3.16.7
https://github.com/metonym/svelte-intersection-observer
https://www.bennadel.com/blog/3954-intersectionobserver-api-performance-many-vs-shared-in-angular-11-0-5.htm -->
https://www.bennadel.com/blog/3954-intersectionobserver-api-performance-many-vs-shared-in-angular-11-0-5.htm -->
1 change: 0 additions & 1 deletion src/lib/ui/MultiSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
}
function selectOption(option: SelectOption) {
console.log({option})
if (selectedOptions[option.value])
remove(option.value);
else
Expand Down
45 changes: 45 additions & 0 deletions src/lib/ui/SimpleButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script lang="ts">
export let onclick: (
e: MouseEvent & {
currentTarget: EventTarget & HTMLButtonElement;
},
) => any = undefined;
export let type: "button" | "submit" = "button";
export let loading = false;
export let active = false;
export let disabled = false;
export let title: string = undefined;
$: disable = disabled || loading;
async function runWithSpinner(event) {
if (onclick) {
loading = true;
try {
await onclick(event);
} catch (err) {
console.error(err);
alert(err);
}
loading = false;
}
}
</script>

<button
class:active
class:disabled={disable}
class={$$props.class}
{type}
{title}
on:click={runWithSpinner}
disabled={disable}
>
<slot />
{#if loading}
<span
class="i-gg-spinner animate-spin ml-1 -mr-1"
style="vertical-align: -2px;"
/>
{/if}
</button>
4 changes: 2 additions & 2 deletions src/lib/ui/Toasts.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@
<!-- Look at https://github.com/beyonk-adventures/svelte-notifications also -->

<!-- To use, add once in root layout:
{#await import('$svelteui/Toasts.svelte') then { default: Toasts }}
{#await import('svelte-pieces/ui/Toasts.svelte') then { default: Toasts }}
<Toasts />
{/await}
And use:
import { toast } from '$svelteui/ui/Toasts.svelte'; // double-check proper route
import { toast } from 'svelte-pieces/ui/Toasts.svelte';
toast('hello world')
toast('hello world', 5000)
-->
32 changes: 29 additions & 3 deletions src/routes/+layout.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
// @ts-ignore - virtual import
import { pages, settings } from 'virtual:kitbook';
import { layoutLoad } from 'kitbook';
export const load = layoutLoad({ pages, settings });
import { settings } from 'virtual:kitbook';
import { groupColocatedModulesIntoPages, layoutLoad, pagesStore } from 'kitbook';
/**
* Vite glob patterns used for building your Kitbook. See https://vitejs.dev/guide/features.html#multiple-patterns.
* Restrict these paths to be able to incrementally adopt Kitbook into your project.
* Alternate extensions are not yet supported.
* Kitbook changes in the future will cause this file to be regenerated. Your glob patterns will be preserved as long as you only edit the patterns inside the array brackets and nothing else.
*/
const components = import.meta.glob(['/src/**/*.svelte']);
const componentsRaw = import.meta.glob(['/src/**/*.svelte'], { as: 'raw' });
const variants = import.meta.glob(['/src/**/*.variants.ts']);
const variantsRaw = import.meta.glob(['/src/**/*.variants.ts'], { as: 'raw' });
const compositions = import.meta.glob(['/src/**/*.composition']);
const compositionsRaw = import.meta.glob(['/src/**/*.composition'], { as: 'raw' });
const markdown = import.meta.glob(['/src/**/*.md', '/README.md']);
const markdownRaw = import.meta.glob(['/src/**/*.md', '/README.md'], { as: 'raw' });
export const _pages = groupColocatedModulesIntoPages({ components, componentsRaw, variants, variantsRaw, compositions, compositionsRaw, markdown, markdownRaw });
let firstLoad = true;
if (firstLoad) {
pagesStore.set(_pages);
firstLoad = false;
}
if (import.meta.hot) {
import.meta.hot.accept((module) => {
if (module?._pages)
pagesStore.set(module._pages);
});
}
export const load = layoutLoad({ pages: _pages, settings });
2 changes: 1 addition & 1 deletion src/routes/[...file]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export let data;

<MainPage {data} />

<!-- kitbook route files auto-generated by kitbook@1.0.0-alpha.50^ - do not edit as they will be overwritten next time kitbook updates routing -->
<!-- Kitbook route files were auto-generated by kitbook@1.0.0-beta.6^ - Do not edit as they will be overwritten next time kitbook updates routing. -->
1 change: 0 additions & 1 deletion src/routes/[...file]/_page.md

This file was deleted.

3 changes: 0 additions & 3 deletions src/routes/sandbox/[...file]/_page.md

This file was deleted.

0 comments on commit 85b249c

Please sign in to comment.