From e0ffda82e482c583f002eef869d9dd276609ee32 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <9.shivamgupta.6@gmail.com>
Date: Sat, 8 Aug 2026 23:35:30 +0530
Subject: [PATCH] fix: extend scroll-fade treatment to provider tabs and data
tables
Apply the same hidden-scrollbar + edge-fade fix to two more overflow
spots found by a repo-wide scan:
- Application/Compose "General" tab source-provider picker
(GitHub/GitLab/Bitbucket/Gitea/Git/Raw/Docker/Drop) had the same bare
overflow-auto tab row as the service detail pages.
- The shared ui/table.tsx container wraps nearly every data table in
the app with overflow-x-auto and no scroll affordance at all.
Refactor ScrollFadeContainer to expose the underlying scroll-fade logic
as a reusable useScrollFade hook + ScrollFadeEdges overlay, since
Table needs the fade attached to its own existing container div rather
than an extra wrapping div. ScrollFadeContainer's own behavior and API
are unchanged.
---
.../application/general/generic/show.tsx | 5 +-
.../compose/general/generic/show.tsx | 5 +-
.../shared/scroll-fade-container.tsx | 65 +++++++++++++------
apps/dokploy/components/ui/table.tsx | 14 +++-
4 files changed, 64 insertions(+), 25 deletions(-)
diff --git a/apps/dokploy/components/dashboard/application/general/generic/show.tsx b/apps/dokploy/components/dashboard/application/general/generic/show.tsx
index 6cf4022c1..5f1940b0b 100644
--- a/apps/dokploy/components/dashboard/application/general/generic/show.tsx
+++ b/apps/dokploy/components/dashboard/application/general/generic/show.tsx
@@ -14,6 +14,7 @@ import {
GitIcon,
GitlabIcon,
} from "@/components/icons/data-tools-icons";
+import { ScrollFadeContainer } from "@/components/shared/scroll-fade-container";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { api } from "@/utils/api";
@@ -153,7 +154,7 @@ export const ShowProviderForm = ({ applicationId }: Props) => {
setSab(e as TabState);
}}
>
-
+
{
Drop
-
+
{githubProviders && githubProviders?.length > 0 ? (
diff --git a/apps/dokploy/components/dashboard/compose/general/generic/show.tsx b/apps/dokploy/components/dashboard/compose/general/generic/show.tsx
index c2b6f4d0e..b47c9d359 100644
--- a/apps/dokploy/components/dashboard/compose/general/generic/show.tsx
+++ b/apps/dokploy/components/dashboard/compose/general/generic/show.tsx
@@ -10,6 +10,7 @@ import {
GitIcon,
GitlabIcon,
} from "@/components/icons/data-tools-icons";
+import { ScrollFadeContainer } from "@/components/shared/scroll-fade-container";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { api } from "@/utils/api";
@@ -142,7 +143,7 @@ export const ShowProviderFormCompose = ({ composeId }: Props) => {
setSab(e as TabState);
}}
>
-
+
{
Raw
-
+
{githubProviders && githubProviders?.length > 0 ? (
diff --git a/apps/dokploy/components/shared/scroll-fade-container.tsx b/apps/dokploy/components/shared/scroll-fade-container.tsx
index 16112b0bd..885ec8bc7 100644
--- a/apps/dokploy/components/shared/scroll-fade-container.tsx
+++ b/apps/dokploy/components/shared/scroll-fade-container.tsx
@@ -1,13 +1,10 @@
import { cn } from "@/lib/utils";
-import { useEffect, useRef, useState } from "react";
+import { type RefObject, useEffect, useRef, useState } from "react";
-interface Props {
- children: React.ReactNode;
- className?: string;
-}
-
-export const ScrollFadeContainer = ({ children, className }: Props) => {
- const ref = useRef(null);
+export const useScrollFade = (
+ deps: unknown[] = [],
+): [RefObject, boolean, boolean] => {
+ const ref = useRef(null);
const [canScrollLeft, setCanScrollLeft] = useState(false);
const [canScrollRight, setCanScrollRight] = useState(false);
@@ -32,7 +29,43 @@ export const ScrollFadeContainer = ({ children, className }: Props) => {
el.removeEventListener("scroll", updateFades);
resizeObserver.disconnect();
};
- }, [children]);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, deps);
+
+ return [ref, canScrollLeft, canScrollRight];
+};
+
+export const ScrollFadeEdges = ({
+ canScrollLeft,
+ canScrollRight,
+}: {
+ canScrollLeft: boolean;
+ canScrollRight: boolean;
+}) => (
+ <>
+
+
+ >
+);
+
+interface Props {
+ children: React.ReactNode;
+ className?: string;
+}
+
+export const ScrollFadeContainer = ({ children, className }: Props) => {
+ const [ref, canScrollLeft, canScrollRight] =
+ useScrollFade([children]);
return (
@@ -42,17 +75,9 @@ export const ScrollFadeContainer = ({ children, className }: Props) => {
>
{children}
-
-
);
diff --git a/apps/dokploy/components/ui/table.tsx b/apps/dokploy/components/ui/table.tsx
index da95d3590..043d5e222 100644
--- a/apps/dokploy/components/ui/table.tsx
+++ b/apps/dokploy/components/ui/table.tsx
@@ -2,19 +2,31 @@
import type * as React from "react";
+import {
+ ScrollFadeEdges,
+ useScrollFade,
+} from "@/components/shared/scroll-fade-container";
import { cn } from "@/lib/utils";
function Table({ className, ...props }: React.ComponentProps<"table">) {
+ const [ref, canScrollLeft, canScrollRight] =
+ useScrollFade([props.children]);
+
return (
);
}