summaryrefslogtreecommitdiff
path: root/apps/web/src/components/editor/media-panel/tabbar.tsx
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-08-31 21:51:31 +0200
committerMaze Winther <mazewinther@gmail.com>2025-08-31 21:51:31 +0200
commit8eabbeae7c4c24bf8369deb336eaf38f4967f285 (patch)
treee0ed634ac9c937b73c34640dff5ab8138604ebf2 /apps/web/src/components/editor/media-panel/tabbar.tsx
parent2c5d5dc23437e288d7e6936e0337583dc8dbc782 (diff)
downloadopencut-8eabbeae7c4c24bf8369deb336eaf38f4967f285.tar.gz
more changes
Diffstat (limited to 'apps/web/src/components/editor/media-panel/tabbar.tsx')
-rw-r--r--apps/web/src/components/editor/media-panel/tabbar.tsx52
1 files changed, 50 insertions, 2 deletions
diff --git a/apps/web/src/components/editor/media-panel/tabbar.tsx b/apps/web/src/components/editor/media-panel/tabbar.tsx
index 56437508..e2bfdff7 100644
--- a/apps/web/src/components/editor/media-panel/tabbar.tsx
+++ b/apps/web/src/components/editor/media-panel/tabbar.tsx
@@ -7,13 +7,45 @@ import {
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
+import { useEffect, useRef, useState } from "react";
export function TabBar() {
const { activeTab, setActiveTab } = useMediaPanelStore();
+ const scrollRef = useRef<HTMLDivElement>(null);
+ const [showTopFade, setShowTopFade] = useState(false);
+ const [showBottomFade, setShowBottomFade] = useState(false);
+
+ const checkScrollPosition = () => {
+ const element = scrollRef.current;
+ if (!element) return;
+
+ const { scrollTop, scrollHeight, clientHeight } = element;
+ setShowTopFade(scrollTop > 0);
+ setShowBottomFade(scrollTop < scrollHeight - clientHeight - 1);
+ };
+
+ useEffect(() => {
+ const element = scrollRef.current;
+ if (!element) return;
+
+ checkScrollPosition();
+ element.addEventListener("scroll", checkScrollPosition);
+
+ const resizeObserver = new ResizeObserver(checkScrollPosition);
+ resizeObserver.observe(element);
+
+ return () => {
+ element.removeEventListener("scroll", checkScrollPosition);
+ resizeObserver.disconnect();
+ };
+ }, []);
return (
- <div className="flex">
- <div className="h-full px-4 flex flex-col justify-start items-center gap-5 overflow-x-auto scrollbar-x-hidden relative w-full py-4">
+ <div className="flex relative">
+ <div
+ ref={scrollRef}
+ className="h-full px-4 flex flex-col justify-start items-center gap-5 overflow-y-auto scrollbar-hidden relative w-full py-4"
+ >
{(Object.keys(tabs) as Tab[]).map((tabKey) => {
const tab = tabs[tabKey];
return (
@@ -46,6 +78,22 @@ export function TabBar() {
);
})}
</div>
+
+ <FadeOverlay direction="top" show={showTopFade} />
+ <FadeOverlay direction="bottom" show={showBottomFade} />
</div>
);
}
+
+function FadeOverlay({ direction, show }: { direction: "top" | "bottom", show: boolean }) {
+ return (
+ <div
+ className={cn(
+ "absolute left-0 right-0 h-6 pointer-events-none z-[101] transition-opacity duration-200",
+ direction === "top" && show
+ ? "top-0 bg-gradient-to-b from-panel to-transparent"
+ : "bottom-0 bg-gradient-to-t from-panel to-transparent"
+ )}
+ />
+ );
+} \ No newline at end of file