mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-09-14 11:06:15 +05:00
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.
This commit is contained in:
parent
0a95436d16
commit
e0ffda82e4
@ -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);
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-row items-center justify-between w-full overflow-auto">
|
||||
<ScrollFadeContainer className="flex flex-row items-center justify-between w-full">
|
||||
<TabsList
|
||||
variant="line"
|
||||
className="flex gap-4 justify-start bg-transparent"
|
||||
@ -208,7 +209,7 @@ export const ShowProviderForm = ({ applicationId }: Props) => {
|
||||
Drop
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
</ScrollFadeContainer>
|
||||
|
||||
<TabsContent value="github" className="w-full p-2">
|
||||
{githubProviders && githubProviders?.length > 0 ? (
|
||||
|
||||
@ -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);
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-row items-center justify-between w-full overflow-auto">
|
||||
<ScrollFadeContainer className="flex flex-row items-center justify-between w-full">
|
||||
<TabsList
|
||||
variant="line"
|
||||
className="flex gap-4 justify-start bg-transparent"
|
||||
@ -189,7 +190,7 @@ export const ShowProviderFormCompose = ({ composeId }: Props) => {
|
||||
Raw
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
</ScrollFadeContainer>
|
||||
|
||||
<TabsContent value="github" className="w-full p-2">
|
||||
{githubProviders && githubProviders?.length > 0 ? (
|
||||
|
||||
@ -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<HTMLDivElement>(null);
|
||||
export const useScrollFade = <T extends HTMLElement>(
|
||||
deps: unknown[] = [],
|
||||
): [RefObject<T | null>, boolean, boolean] => {
|
||||
const ref = useRef<T>(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;
|
||||
}) => (
|
||||
<>
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-y-0 left-0 w-8 bg-gradient-to-r from-background to-transparent transition-opacity",
|
||||
canScrollLeft ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-y-0 right-0 w-8 bg-gradient-to-l from-background to-transparent transition-opacity",
|
||||
canScrollRight ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const ScrollFadeContainer = ({ children, className }: Props) => {
|
||||
const [ref, canScrollLeft, canScrollRight] =
|
||||
useScrollFade<HTMLDivElement>([children]);
|
||||
|
||||
return (
|
||||
<div className="relative min-w-0">
|
||||
@ -42,17 +75,9 @@ export const ScrollFadeContainer = ({ children, className }: Props) => {
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-y-0 left-0 w-8 bg-gradient-to-r from-background to-transparent transition-opacity",
|
||||
canScrollLeft ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-y-0 right-0 w-8 bg-gradient-to-l from-background to-transparent transition-opacity",
|
||||
canScrollRight ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
<ScrollFadeEdges
|
||||
canScrollLeft={canScrollLeft}
|
||||
canScrollRight={canScrollRight}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -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<HTMLDivElement>([props.children]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
data-slot="table-container"
|
||||
className="relative w-full overflow-x-auto"
|
||||
className="relative w-full overflow-x-auto no-scrollbar"
|
||||
>
|
||||
<table
|
||||
data-slot="table"
|
||||
className={cn("w-full caption-bottom text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
<ScrollFadeEdges
|
||||
canScrollLeft={canScrollLeft}
|
||||
canScrollRight={canScrollRight}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user