From 10f033ba41b4b420e27d4b068033c29a5ff69966 Mon Sep 17 00:00:00 2001
From: Ruslan Bayandinov <45530296+wazsone@users.noreply.github.com>
Date: Fri, 2 Jun 2023 14:07:17 +0700
Subject: [PATCH] [UBER-129] Fix scroll after collapsing a list header (#3330)

Signed-off-by: Ruslan Bayandinov <wazsone@ya.ru>
---
 packages/ui/src/components/Scroller.svelte    | 35 ++++++++++++-------
 .../src/components/list/List.svelte           |  1 +
 .../src/components/list/ListCategories.svelte |  1 +
 .../src/components/list/ListCategory.svelte   |  6 +---
 .../src/components/list/ListHeader.svelte     |  1 -
 .../src/components/list/ListView.svelte       | 11 ++++--
 6 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/packages/ui/src/components/Scroller.svelte b/packages/ui/src/components/Scroller.svelte
index 0d2b3b654d..dc3f7ea38d 100644
--- a/packages/ui/src/components/Scroller.svelte
+++ b/packages/ui/src/components/Scroller.svelte
@@ -453,6 +453,14 @@
       ? 'visible'
       : 'hidden'
   let scrollY: number = 0
+
+  let safariScrollJumpfix: boolean = true
+  export const enableSafariScrollJumpFix = (enable: boolean): void => {
+    if (enable) {
+      scrollY = divScroll?.scrollTop ?? 0
+    }
+    safariScrollJumpfix = enable
+  }
 </script>
 
 <svelte:window on:resize={_resize} />
@@ -476,24 +484,25 @@
       }}
       class="scroll relative flex-shrink"
       style:overflow-x={horizontal ? 'auto' : 'hidden'}
-      on:scroll={(evt) => {
+      on:scroll={() => {
         if ($tooltipstore.label !== undefined) closeTooltip()
-        const newPos = divScroll?.scrollTop ?? 0
 
         // TODO: Workaround: https://front.hc.engineering/workbench/platform/tracker/TSK-760
         // In Safari scroll could jump on click, with no particular reason.
-
-        if (
-          !scrolling &&
-          !isScrolling &&
-          scrollY !== 0 &&
-          Math.abs(newPos - scrollY) > 100 &&
-          divScroll !== undefined &&
-          isSafari()
-        ) {
-          divScroll.scrollTop = scrollY
+        if (safariScrollJumpfix) {
+          const newPos = divScroll?.scrollTop ?? 0
+          if (
+            !scrolling &&
+            !isScrolling &&
+            scrollY !== 0 &&
+            Math.abs(newPos - scrollY) > 100 &&
+            divScroll !== undefined &&
+            isSafari()
+          ) {
+            divScroll.scrollTop = scrollY
+          }
+          scrollY = divScroll?.scrollTop ?? 0
         }
-        scrollY = divScroll?.scrollTop ?? 0
       }}
     >
       <div
diff --git a/plugins/view-resources/src/components/list/List.svelte b/plugins/view-resources/src/components/list/List.svelte
index 09267efb2b..fa8be2960a 100644
--- a/plugins/view-resources/src/components/list/List.svelte
+++ b/plugins/view-resources/src/components/list/List.svelte
@@ -148,6 +148,7 @@
     on:select-prev={(evt) => {
       select(-2, evt.detail)
     }}
+    on:collapsed
   />
 </div>
 
diff --git a/plugins/view-resources/src/components/list/ListCategories.svelte b/plugins/view-resources/src/components/list/ListCategories.svelte
index 73c4e13694..6536b90f1c 100644
--- a/plugins/view-resources/src/components/list/ListCategories.svelte
+++ b/plugins/view-resources/src/components/list/ListCategories.svelte
@@ -319,6 +319,7 @@
         index: e.detail.index + getInitIndex(categories, i)
       })
     }}
+    on:collapsed
     {flatHeaders}
     {disableHeader}
     {props}
diff --git a/plugins/view-resources/src/components/list/ListCategory.svelte b/plugins/view-resources/src/components/list/ListCategory.svelte
index c12b09102d..43f326093f 100644
--- a/plugins/view-resources/src/components/list/ListCategory.svelte
+++ b/plugins/view-resources/src/components/list/ListCategory.svelte
@@ -390,6 +390,7 @@
               $focusStore = { provider: $focusStore.provider }
             }
           }
+          dispatch('collapsed', { div })
         }
         localStorage.setItem(categoryCollapseKey, collapsed ? 'true' : 'false')
       }}
@@ -460,11 +461,6 @@
 </div>
 
 <style lang="scss">
-  .expandCollapse {
-    overflow: hidden;
-    transition: height 0.3s ease-out;
-    height: auto;
-  }
   .zero-container {
     border-radius: 0.25rem;
 
diff --git a/plugins/view-resources/src/components/list/ListHeader.svelte b/plugins/view-resources/src/components/list/ListHeader.svelte
index 955b8fd1d0..1c676abb08 100644
--- a/plugins/view-resources/src/components/list/ListHeader.svelte
+++ b/plugins/view-resources/src/components/list/ListHeader.svelte
@@ -198,7 +198,6 @@
 
 <style lang="scss">
   .categoryHeader {
-    position: relative;
     position: sticky;
     top: 0;
     padding: 0 2.5rem 0 0.75rem;
diff --git a/plugins/view-resources/src/components/list/ListView.svelte b/plugins/view-resources/src/components/list/ListView.svelte
index bd49b87d3d..57852f82d1 100644
--- a/plugins/view-resources/src/components/list/ListView.svelte
+++ b/plugins/view-resources/src/components/list/ListView.svelte
@@ -21,6 +21,7 @@
   export let props: Record<string, any> = {}
 
   let list: List
+  let scroll: Scroller
 
   const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
     if (dir === 'vertical') {
@@ -42,6 +43,7 @@
 
 <div class="w-full h-full py-4 clear-mins">
   <Scroller
+    bind:this={scroll}
     fade={{ multipler: { top: 2.75 * viewOptions.groupBy.length, bottom: 0 } }}
     padding={'0 1rem'}
     noFade
@@ -67,8 +69,13 @@
       on:check={(event) => {
         listProvider.updateSelection(event.detail.docs, event.detail.value)
       }}
-      on:content={(evt) => {
-        listProvider.update(evt.detail)
+      on:content={(event) => {
+        listProvider.update(event.detail)
+      }}
+      on:collapsed={(event) => {
+        scroll.enableSafariScrollJumpFix(false)
+        event.detail.div.scrollIntoView(true)
+        scroll.enableSafariScrollJumpFix(true)
       }}
     />
   </Scroller>