Quellcode durchsuchen

feat(app): improve projects sidebar reactivity (#34391)

Co-authored-by: Brendan Allan <git@brendonovich.dev>
Aarav Sareen vor 2 Monaten
Ursprung
Commit
2070fd9bc2
2 geänderte Dateien mit 108 neuen und 38 gelöschten Zeilen
  1. 62 0
      packages/app/src/index.css
  2. 46 38
      packages/app/src/pages/home.tsx

+ 62 - 0
packages/app/src/index.css

@@ -171,4 +171,66 @@
       transform: rotate(360deg);
     }
   }
+
+  @keyframes home-projects-fade-top {
+    from {
+      visibility: hidden;
+    }
+    to {
+      visibility: visible;
+    }
+  }
+
+  @keyframes home-projects-fade-bottom {
+    from {
+      visibility: visible;
+    }
+    to {
+      visibility: hidden;
+    }
+  }
+
+  [data-slot="home-projects-scroll"] {
+    timeline-scope: --home-projects-scroll;
+  }
+
+  [data-slot="home-projects-scroll"]::before,
+  [data-slot="home-projects-scroll"]::after {
+    content: "";
+    position: absolute;
+    left: 0;
+    right: 0;
+    z-index: 10;
+    height: 16px;
+    pointer-events: none;
+    visibility: hidden;
+  }
+
+  [data-slot="home-projects-scroll"]::before {
+    top: 0;
+    background: linear-gradient(to bottom, var(--v2-background-bg-base), transparent);
+  }
+
+  [data-slot="home-projects-scroll"]::after {
+    bottom: 0;
+    background: linear-gradient(to top, var(--v2-background-bg-base), transparent);
+  }
+
+  @supports (animation-timeline: --home-projects-scroll) and (timeline-scope: --home-projects-scroll) {
+    [data-slot="home-projects-scroll"] .scroll-view__viewport {
+      scroll-timeline: --home-projects-scroll y;
+    }
+
+    [data-slot="home-projects-scroll"]::before {
+      animation: home-projects-fade-top linear both;
+      animation-timeline: --home-projects-scroll;
+      animation-range: 0 0.1px;
+    }
+
+    [data-slot="home-projects-scroll"]::after {
+      animation: home-projects-fade-bottom linear both;
+      animation-timeline: --home-projects-scroll;
+      animation-range: calc(100% - 1.1px) calc(100% - 1px);
+    }
+  }
 }

+ 46 - 38
packages/app/src/pages/home.tsx

@@ -668,10 +668,10 @@ function HomeProjectColumn(props: {
 
   return (
     <aside
-      class="mt-6 flex min-w-0 flex-col gap-4 lg:mt-14 lg:pt-[52px]"
+      class="mt-6 flex min-h-0 min-w-0 flex-col gap-4 overflow-hidden lg:mt-14 lg:pt-[52px]"
       aria-label={props.language.t("home.projects")}
     >
-      <div class="flex h-7 min-w-0 items-center justify-between pl-1.5">
+      <div class="flex h-7 min-w-0 shrink-0 items-center justify-between pl-1.5">
         <div class={HOME_SECTION_LABEL}>{props.language.t("home.projects")}</div>
         <Show when={global.servers.list().length === 1}>
           <TooltipV2 placement="bottom" value={props.language.t("home.project.add")}>
@@ -688,43 +688,51 @@ function HomeProjectColumn(props: {
           </TooltipV2>
         </Show>
       </div>
-      <Show
-        when={global.servers.list().length > 1}
-        fallback={<HomeProjectList {...props} server={global.servers.list()[0]!} />}
-      >
-        <For each={global.servers.list()}>
-          {(item) => {
-            const key = ServerConnection.key(item)
-            const healthy = () => !!global.servers.health[key]?.healthy
-            const serverCtx = global.ensureServerCtx(item)
-            const projects = () => serverCtx.projects.list()
-            const hasProjects = () => projects().length > 0
-            const collapsed = () => !!state().collapsed[key]
-            return (
-              <div class="flex max-h-[min(572px,calc(100vh_-_300px))] min-w-0 flex-col gap-1 overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
-                <HomeServerRow
-                  server={item}
-                  selected={props.selected.server === key && !props.selected.directory}
-                  collapsed={collapsed()}
-                  health={global.servers.health[key]}
-                  controller={controller}
-                  focusServer={props.focusServer}
-                  chooseProject={props.chooseProject}
-                  openEdit={(server) => dialog.show(() => <DialogServerV2 mode="edit" server={server} />)}
-                  toggleCollapsed={() => setState("collapsed", key, !state().collapsed[key])}
-                  language={props.language}
-                />
-                <Show when={healthy() && hasProjects() && !collapsed()}>
-                  <div class="mx-3 h-px bg-v2-border-border-base" />
-                  <HomeProjectList {...props} server={item} projects={projects()} />
-                </Show>
-              </div>
-            )
-          }}
-        </For>
-      </Show>
+      <ScrollView data-slot="home-projects-scroll" class="min-h-0 min-w-0 shrink">
+        <Show
+          when={global.servers.list().length > 1}
+          fallback={
+            <div class="pr-3">
+              <HomeProjectList {...props} server={global.servers.list()[0]!} />
+            </div>
+          }
+        >
+          <div class="flex min-w-0 flex-col gap-1 pr-3">
+            <For each={global.servers.list()}>
+              {(item) => {
+                const key = ServerConnection.key(item)
+                const healthy = () => !!global.servers.health[key]?.healthy
+                const serverCtx = global.ensureServerCtx(item)
+                const projects = () => serverCtx.projects.list()
+                const hasProjects = () => projects().length > 0
+                const collapsed = () => !!state().collapsed[key]
+                return (
+                  <div class="flex min-w-0 flex-col gap-1">
+                    <HomeServerRow
+                      server={item}
+                      selected={props.selected.server === key && !props.selected.directory}
+                      collapsed={collapsed()}
+                      health={global.servers.health[key]}
+                      controller={controller}
+                      focusServer={props.focusServer}
+                      chooseProject={props.chooseProject}
+                      openEdit={(server) => dialog.show(() => <DialogServerV2 mode="edit" server={server} />)}
+                      toggleCollapsed={() => setState("collapsed", key, !state().collapsed[key])}
+                      language={props.language}
+                    />
+                    <Show when={healthy() && hasProjects() && !collapsed()}>
+                      <div class="mx-3 h-px bg-v2-border-border-base" />
+                      <HomeProjectList {...props} server={item} projects={projects()} />
+                    </Show>
+                  </div>
+                )
+              }}
+            </For>
+          </div>
+        </Show>
+      </ScrollView>
       <HomeUtilityNav
-        class="mt-4 hidden lg:flex"
+        class="mb-8 mt-4 hidden shrink-0 lg:flex"
         openSettings={props.openSettings}
         openHelp={props.openHelp}
         language={props.language}