From 32f2a833c53f8f25d0d6087be23911af5ed5bf13 Mon Sep 17 00:00:00 2001 From: MinamiFunakoshiTR Date: Thu, 22 May 2025 12:46:21 -0700 Subject: [PATCH] makes rootMargin prop units customiasable closes #221 --- src/components/Visible/Visible.mdx | 3 +- src/components/Visible/Visible.stories.svelte | 5 +- src/components/Visible/Visible.svelte | 48 ++++++++++++------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/components/Visible/Visible.mdx b/src/components/Visible/Visible.mdx index f3c25b59..f6f38f4b 100644 --- a/src/components/Visible/Visible.mdx +++ b/src/components/Visible/Visible.mdx @@ -19,7 +19,8 @@ By default, `visible` will switch between `false` and `true` whenever the elemen import { Visible } from '@reuters-graphics/graphics-components'; - + + {#snippet children(visible)} {#if visible}

Visible!

diff --git a/src/components/Visible/Visible.stories.svelte b/src/components/Visible/Visible.stories.svelte index 2529755b..e683ea62 100644 --- a/src/components/Visible/Visible.stories.svelte +++ b/src/components/Visible/Visible.stories.svelte @@ -9,8 +9,9 @@ }); - - + + + {#snippet children(visible)} {#if visible}

Visible!

diff --git a/src/components/Visible/Visible.svelte b/src/components/Visible/Visible.svelte index e1dd30a4..f8860595 100644 --- a/src/components/Visible/Visible.svelte +++ b/src/components/Visible/Visible.svelte @@ -9,14 +9,26 @@ * Useful for loading expensive images or other media and then keeping them around once they're first loaded. */ once?: boolean; - /** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `top`. */ - top?: number; - /** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `bottom`. */ - bottom?: number; - /** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `left`. */ - left?: number; - /** Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `right`. */ - right?: number; + /** + * Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `top`. + * Specify a value and unit (e.g. `px`, `%`, `vw`, `vh`, `rem`, `em`). + */ + top?: { value: number; unit: 'px' | '%' | 'vw' | 'vh' | 'rem' | 'em' }; + /** + * Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `bottom`. + * Specify a value and unit (e.g. `px`, `%`, `vw`, `vh`, `rem`, `em`). + */ + bottom?: { value: number; unit: 'px' | '%' | 'vw' | 'vh' | 'rem' | 'em' }; + /** + * Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `left`. + * Specify a value and unit (e.g. `px`, `%`, `vw`, `vh`, `rem`, `em`). + */ + left?: { value: number; unit: 'px' | '%' | 'vw' | 'vh' | 'rem' | 'em' }; + /** + * Set Intersection Observer [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin) `right`. + * Specify a value and unit (e.g. `px`, `%`, `vw`, `vh`, `rem`, `em`). + */ + right?: { value: number; unit: 'px' | '%' | 'vw' | 'vh' | 'rem' | 'em' }; /** Set the Intersection Observer [threshold](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#threshold). */ threshold?: number; children?: Snippet<[boolean]>; @@ -24,10 +36,10 @@ let { once = false, - top = 0, - bottom = 0, - left = 0, - right = 0, + top = { value: 0, unit: 'px' }, + bottom = { value: 0, unit: 'px' }, + left = { value: 0, unit: 'px' }, + right = { value: 0, unit: 'px' }, threshold = 0, children, }: Props = $props(); @@ -37,7 +49,7 @@ onMount(() => { if (typeof IntersectionObserver !== 'undefined') { - const rootMargin = `${bottom}px ${left}px ${top}px ${right}px`; + const rootMargin = `${bottom.value}${bottom.unit} ${left.value}${left.unit} ${top.value}${top.unit} ${right.value}${right.unit}`; const observer = new IntersectionObserver( (entries) => { @@ -53,17 +65,17 @@ ); if (container) observer.observe(container); return () => { - if (container) observer.observe(container); + if (container) observer.unobserve(container); }; } function handler() { if (container) { const bcr = container.getBoundingClientRect(); visible = - bcr.bottom + bottom > 0 && - bcr.right + right > 0 && - bcr.top - top < window.innerHeight && - bcr.left - left < window.innerWidth; + bcr.bottom + bottom.value > 0 && + bcr.right + right.value > 0 && + bcr.top - top.value < window.innerHeight && + bcr.left - left.value < window.innerWidth; } if (visible && once) { window.removeEventListener('scroll', handler);