From 60bfa1d28cae1dea3f0a764d6d3abfcb1f6da885 Mon Sep 17 00:00:00 2001 From: oyessb <47382101+oyessb@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:58:35 +0100 Subject: [PATCH 1/3] Sticky items for search/select are added by topItemCount prop. When scrolling down a custom TopItemList i used to override sticky div with empty fragment. --- .../VariableBoxContent/VariableBoxContent.tsx | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx index 155acea8..6c96b9aa 100644 --- a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx +++ b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react'; import cl from 'clsx'; import { useTranslation } from 'react-i18next'; import { useDebounce } from '@uidotdev/usehooks'; -import { Virtuoso } from 'react-virtuoso'; +import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; import classes from './VariableBoxContent.module.scss'; import { Checkbox, MixedCheckbox } from '../../Checkbox/Checkbox'; @@ -264,6 +264,38 @@ export function VariableBoxContent({ } }; + //How many items should be sticky + const stickyTopValueCount = hasSevenOrMoreValues + ? 2 + : hasTwoOrMoreValues + ? 1 + : 0; + + const virtuosoRef = useRef(null); + const [lastScrollPosition, setLastScrollPosition] = useState(0); + const [scrollingDown, setScrollingDown] = useState(false); + + const handleVirtuosoScroll = () => { + if (virtuosoRef.current) { + virtuosoRef.current.getState((state) => { + const scrollTop = state.scrollTop; + const isIntentionalScrollUp = scrollTop < lastScrollPosition - 5; + const isIntentionalScrollDown = scrollTop > lastScrollPosition + 5; + + if (isIntentionalScrollDown && !scrollingDown) { + setScrollingDown(true); + } else if (isIntentionalScrollUp && scrollingDown) { + setScrollingDown(false); + } + setLastScrollPosition(scrollTop); + }); + } + }; + + // To override element styling added by Virtuoso when scrolling down + /* eslint-disable-next-line */ + const TopItemListEmptyFragment = () => <>; + return (
@@ -328,6 +360,9 @@ export function VariableBoxContent({ enter: (velocity) => Math.abs(velocity) > 1000, exit: (velocity) => Math.abs(velocity) < 30, }} + topItemCount={stickyTopValueCount} + ref={virtuosoRef} + isScrolling={handleVirtuosoScroll} components={{ ScrollSeekPlaceholder: ({ height }) => ( ), + TopItemList: scrollingDown + ? TopItemListEmptyFragment + : undefined, }} /> )} From ddc5a66d6f9cb15456de4d57487cba335b70aa71 Mon Sep 17 00:00:00 2001 From: oyessb <47382101+oyessb@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:46:52 +0100 Subject: [PATCH 2/3] Replaced isScrolling (start/stop scrolling) with onScroll event which will triggered for every scroll change. --- .../VariableBox/VariableBoxContent/VariableBoxContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx index 6c96b9aa..c9a74318 100644 --- a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx +++ b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx @@ -362,7 +362,7 @@ export function VariableBoxContent({ }} topItemCount={stickyTopValueCount} ref={virtuosoRef} - isScrolling={handleVirtuosoScroll} + onScroll={handleVirtuosoScroll} components={{ ScrollSeekPlaceholder: ({ height }) => ( Date: Mon, 11 Nov 2024 10:47:42 +0100 Subject: [PATCH 3/3] Set scrollingdown to false when search phrase is cleared. Decrease margin sensitivity for scroll. Remove sticky only if search is empty. --- .../VariableBoxContent/VariableBoxContent.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx index c9a74318..2830d227 100644 --- a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx +++ b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx @@ -209,6 +209,9 @@ export function VariableBoxContent({ { setSearch(value); + if(value === '') { + setScrollingDown(false); + } }} variant="inVariableBox" showLabel={false} @@ -279,8 +282,8 @@ export function VariableBoxContent({ if (virtuosoRef.current) { virtuosoRef.current.getState((state) => { const scrollTop = state.scrollTop; - const isIntentionalScrollUp = scrollTop < lastScrollPosition - 5; - const isIntentionalScrollDown = scrollTop > lastScrollPosition + 5; + const isIntentionalScrollUp = scrollTop < lastScrollPosition - 2; + const isIntentionalScrollDown = scrollTop > lastScrollPosition + 2; if (isIntentionalScrollDown && !scrollingDown) { setScrollingDown(true); @@ -371,7 +374,7 @@ export function VariableBoxContent({ width={50 + Math.ceil(Math.random() * 15) + '%'} /> ), - TopItemList: scrollingDown + TopItemList: (scrollingDown && search === '') ? TopItemListEmptyFragment : undefined, }}