diff --git a/src/lib/actions/visible.ts b/src/lib/actions/visible.ts new file mode 100644 index 000000000..3545b9c54 --- /dev/null +++ b/src/lib/actions/visible.ts @@ -0,0 +1,60 @@ +import { isVisible } from '$lib/utils/isVisible'; +import type { Action } from 'svelte/action'; + +type Args = + | { + top?: number; + bottom?: number; + left?: number; + right?: number; + } + | undefined; + +export const visible: Action< + HTMLElement, + Args, + { 'on:visible': (e: CustomEvent) => void } +> = (node, args) => { + let visible = false; + + const createVisibilityHandler = (newArgs: Args) => { + const argsWithDefaults = { + top: 0, + bottom: window.innerHeight, + left: 0, + right: window.innerWidth, + ...newArgs + }; + return () => { + const prev = visible; + visible = isVisible(node, argsWithDefaults); + if (prev !== visible) { + node.dispatchEvent(new CustomEvent('visible', { detail: visible })); + } + }; + }; + + let handleVisibility = createVisibilityHandler(args); + + function destroy() { + window.removeEventListener('scroll', handleVisibility); + window.removeEventListener('resize', handleVisibility); + } + + function update(args: Args) { + destroy(); + handleVisibility = createVisibilityHandler(args); + window.addEventListener('scroll', handleVisibility); + window.addEventListener('resize', handleVisibility); + } + + update(args); + + return { + update, + destroy() { + window.removeEventListener('scroll', handleVisibility); + window.removeEventListener('resize', handleVisibility); + } + }; +}; diff --git a/src/lib/layouts/Main.svelte b/src/lib/layouts/Main.svelte index 62921a44b..6806fc9dc 100644 --- a/src/lib/layouts/Main.svelte +++ b/src/lib/layouts/Main.svelte @@ -8,6 +8,7 @@ + (scrollDir = getScrollDir())} /> +
@@ -327,8 +342,19 @@ aw-u-padding-block-start-80 aw-u-filter-blur-8 u-position-sticky u-z-index-5" style="--inset-block-start:1rem" > -
- Compare plans +
+ {#key activeTable} +
+ {activeTable ?? ''} +
+ {/key}
@@ -363,10 +389,24 @@ class="aw-compare-table aw-sub-body-400" class:is-open-in-mobile={isOpen} use:melt={$item(table.title)} + use:visible={{ + top: 128 + }} + on:visible={(e) => { + const isVisible = e.detail; + visibleTables.update((p) => { + if (isVisible) { + return [...p, table.title]; + } else { + return p.filter((t) => t !== table.title); + } + }); + }} >