(
const view = views?.get(viewId) as YDatabaseView | null;
if (!view) return null;
- const databaseLayout = Number(view.get(YjsDatabaseKey.layout)) as DatabaseViewLayout;
- const folderView = viewId === iidIndex ? meta : meta?.children?.find((v) => v.view_id === viewId);
-
- const name = folderView?.name || view.get(YjsDatabaseKey.name) || t('untitled');
return (
-
{
- if (el) {
- tabRefs.current.set(viewId, el);
- } else {
- tabRefs.current.delete(viewId);
- }
- }}
- >
- {
- // For left-click, let Radix UI tabs handle it via onValueChange
- if (e.button === 0) {
- return;
- }
-
- // For right-click and other buttons, prevent default and handle menu
- e.preventDefault();
- e.stopPropagation();
-
- if (readOnly) return;
-
- if (viewId !== menuViewId) {
- setMenuViewId(viewId);
- } else {
- setMenuViewId(null);
- }
- }}
- className={'flex items-center gap-1.5 overflow-hidden'}
- >
-
-
-
-
- {
- e.preventDefault();
- }}
- className={'flex-1 truncate'}
- >
- {name || t('grid.title.placeholder')}
-
-
-
- {name}
-
-
-
- {
- if (!open) {
- setMenuViewId(null);
- }
- }}
- open={menuViewId === viewId}
- >
-
-
-
- e.preventDefault()}
- >
- {menuView && (
- {
- setMenuViewId(null);
- }}
- onOpenDeleteModal={(viewId: string) => {
- setDeleteConfirmOpen(viewId);
- }}
- onOpenRenameModal={(viewId: string) => {
- setRenameViewId(viewId);
- }}
- deleteDisabled={viewId === iidIndex && visibleViewIds.length > 1}
- view={menuView}
- onUpdatedIcon={reloadView}
- />
- )}
-
-
-
+ viewId={viewId}
+ view={view}
+ meta={meta}
+ iidIndex={iidIndex}
+ menuViewId={menuViewId}
+ readOnly={!!readOnly}
+ visibleViewIds={visibleViewIds}
+ onSetMenuViewId={setMenuViewId}
+ onOpenDeleteModal={setDeleteConfirmOpen}
+ onOpenRenameModal={setRenameViewId}
+ onReloadView={reloadView}
+ setTabRef={setTabRef}
+ />
);
})}
@@ -473,13 +347,17 @@ export const DatabaseTabs = forwardRef
(
(
);
}
);
+
+DatabaseTabs.displayName = 'DatabaseTabs';
diff --git a/src/components/database/components/tabs/useTabScroller.ts b/src/components/database/components/tabs/useTabScroller.ts
new file mode 100644
index 00000000..e61f4a5b
--- /dev/null
+++ b/src/components/database/components/tabs/useTabScroller.ts
@@ -0,0 +1,65 @@
+import { useCallback, useEffect, useState } from 'react';
+
+export const useTabScroller = () => {
+ const [scrollerContainer, setScrollerContainer] = useState(null);
+ const [showScrollRightButton, setShowScrollRightButton] = useState(false);
+ const [showScrollLeftButton, setShowScrollLeftButton] = useState(false);
+
+ const handleObserverScroller = useCallback(() => {
+ if (scrollerContainer) {
+ const scrollWidth = scrollerContainer.scrollWidth;
+ const clientWidth = scrollerContainer.clientWidth;
+
+ setShowScrollRightButton(
+ scrollWidth > clientWidth && scrollerContainer.scrollLeft + 1 < scrollWidth - clientWidth
+ );
+ setShowScrollLeftButton(scrollerContainer.scrollLeft > 5);
+ }
+ }, [scrollerContainer]);
+
+ useEffect(() => {
+ if (!scrollerContainer) return;
+ const onResize = () => {
+ handleObserverScroller();
+ };
+
+ // Initial call
+ onResize();
+
+ const observer = new ResizeObserver(onResize);
+
+ observer.observe(scrollerContainer);
+
+ return () => {
+ observer.disconnect();
+ };
+ }, [handleObserverScroller, scrollerContainer]);
+
+ const scrollLeft = useCallback(() => {
+ if (scrollerContainer) {
+ scrollerContainer.scrollTo({
+ left: scrollerContainer.scrollLeft - 200,
+ behavior: 'smooth',
+ });
+ }
+ }, [scrollerContainer]);
+
+ const scrollRight = useCallback(() => {
+ if (scrollerContainer) {
+ scrollerContainer.scrollTo({
+ left: scrollerContainer.scrollLeft + 200,
+ behavior: 'smooth',
+ });
+ }
+ }, [scrollerContainer]);
+
+ return {
+ setScrollerContainer,
+ showScrollLeftButton,
+ showScrollRightButton,
+ scrollLeft,
+ scrollRight,
+ handleObserverScroller,
+ };
+};
+