summaryrefslogtreecommitdiff
path: root/shared/components/src/actions/updateScrollAndWindowDependentVisuals.ts
diff options
context:
space:
mode:
Diffstat (limited to 'shared/components/src/actions/updateScrollAndWindowDependentVisuals.ts')
-rw-r--r--shared/components/src/actions/updateScrollAndWindowDependentVisuals.ts48
1 files changed, 48 insertions, 0 deletions
diff --git a/shared/components/src/actions/updateScrollAndWindowDependentVisuals.ts b/shared/components/src/actions/updateScrollAndWindowDependentVisuals.ts
new file mode 100644
index 0000000..b934e37
--- /dev/null
+++ b/shared/components/src/actions/updateScrollAndWindowDependentVisuals.ts
@@ -0,0 +1,48 @@
+import { debounce } from '@amp/web-app-components/src/utils/debounce';
+import { throttle } from '@amp/web-app-components/src/utils/throttle';
+/**
+ * Dynamically change header and bottom gradient style when scrolling within a modal, and on window resize
+ */
+export function updateScrollAndWindowDependentVisuals(node) {
+ let animationRequest;
+ const handleScroll = () => {
+ // Get scroll details
+ const { scrollHeight, scrollTop, offsetHeight } = node;
+ const maxScroll = scrollHeight - offsetHeight;
+
+ // Calculate whether content is scrolled
+ const contentIsScrolling = scrollTop > 1;
+
+ // Calculate if bottom gradient should be hidden
+ const scrollingNotPossible = maxScroll === 0;
+ const pastMaxScroll = scrollTop >= maxScroll;
+ const hideGradient = scrollingNotPossible || pastMaxScroll;
+
+ if (animationRequest) {
+ window.cancelAnimationFrame(animationRequest);
+ }
+
+ animationRequest = window.requestAnimationFrame(() =>
+ node.dispatchEvent(
+ new CustomEvent('scrollStatus', {
+ detail: { contentIsScrolling, hideGradient },
+ }),
+ ),
+ );
+ };
+
+ const onResize = throttle(handleScroll, 250);
+ const onScroll = debounce(handleScroll, 50);
+ node.addEventListener('scroll', onScroll, { capture: true, passive: true });
+ window.addEventListener('resize', onResize);
+
+ return {
+ destroy() {
+ node.removeEventListener('scroll', onScroll, { capture: true });
+ window.removeEventListener('resize', onResize);
+ if (animationRequest) {
+ window.cancelAnimationFrame(animationRequest);
+ }
+ },
+ };
+}