feat: add floating "Show All" button when tables are out of view (#787)

* feat: add floating "Show All" button when tables are out of view

* fix view of show all for mobile

* fix

---------

Co-authored-by: Guy Ben-Aharon <baguy3@gmail.com>
This commit is contained in:
Jonathan Fishner
2025-07-27 16:25:14 +03:00
committed by GitHub
parent 87836e53d1
commit bda150d4b6
3 changed files with 88 additions and 10 deletions

View File

@@ -92,6 +92,8 @@ import type { Area } from '@/lib/domain/area';
import { updateTablesParentAreas, getTablesInArea } from './area-utils';
import { CanvasFilter } from './canvas-filter/canvas-filter';
import { useHotkeys } from 'react-hotkeys-hook';
import { ShowAllButton } from './show-all-button';
import { useIsLostInCanvas } from './hooks/use-is-lost-in-canvas';
const HIGHLIGHTED_EDGE_Z_INDEX = 1;
const DEFAULT_EDGE_Z_INDEX = 0;
@@ -164,6 +166,7 @@ export const Canvas: React.FC<CanvasProps> = ({ initialTables }) => {
>([]);
const { toast } = useToast();
const { t } = useTranslation();
const { isLostInCanvas } = useIsLostInCanvas();
const {
tables,
areas,
@@ -1275,6 +1278,25 @@ export const Canvas: React.FC<CanvasProps> = ({ initialTables }) => {
</Button>
</Controls>
) : null}
{isLostInCanvas ? (
<Controls
position={
isDesktop ? 'bottom-center' : 'top-center'
}
orientation="horizontal"
showZoom={false}
showFitView={false}
showInteractive={false}
className="!shadow-none"
style={{
[isDesktop ? 'bottom' : 'top']: isDesktop
? '70px'
: '70px',
}}
>
<ShowAllButton />
</Controls>
) : null}
<Controls
position={isDesktop ? 'bottom-center' : 'top-center'}
orientation="horizontal"

View File

@@ -0,0 +1,65 @@
import React, { useCallback, useEffect, useState } from 'react';
import { Button } from '@/components/button/button';
import { Info } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useCanvas } from '@/hooks/use-canvas';
export interface ShowAllButtonProps {}
export const ShowAllButton: React.FC<ShowAllButtonProps> = () => {
const { fitView } = useCanvas();
const [visible, setVisible] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setVisible(true);
}, 0);
return () => clearTimeout(timer);
}, []);
const showAll = useCallback(() => {
fitView({
duration: 500,
padding: 0.1,
maxZoom: 0.8,
});
}, [fitView]);
return (
<div
className={cn(
'transition-all duration-300 ease-in-out',
visible
? 'translate-y-0 opacity-100'
: 'pointer-events-none translate-y-4 opacity-0'
)}
>
<div className="sm:hidden">
<Button
onClick={showAll}
size="sm"
className="h-fit rounded-lg bg-slate-900 px-4 py-1.5 text-xs text-white shadow-lg hover:bg-slate-800 dark:bg-slate-700 dark:hover:bg-slate-600"
>
Show All
</Button>
</div>
<div className="hidden items-center gap-2 rounded-lg bg-slate-900 px-3 py-2 shadow-lg sm:flex">
<div className="flex size-6 items-center justify-center rounded-full bg-pink-600">
<Info className="size-4 text-white" />
</div>
<span className="text-sm text-white">
Your content is out of view
</span>
<Button
onClick={showAll}
size="sm"
className="ml-2 h-fit rounded-lg bg-slate-700 px-4 py-1.5 text-xs text-white hover:bg-slate-600 dark:hover:bg-slate-800"
>
Show All
</Button>
</div>
</div>
);
};

View File

@@ -14,7 +14,6 @@ import { useTranslation } from 'react-i18next';
import { Button } from '@/components/button/button';
import { keyboardShortcutsForOS } from '@/context/keyboard-shortcuts-context/keyboard-shortcuts';
import { KeyboardShortcutAction } from '@/context/keyboard-shortcuts-context/keyboard-shortcuts';
import { useIsLostInCanvas } from '../hooks/use-is-lost-in-canvas';
import { useCanvas } from '@/hooks/use-canvas';
import { useChartDB } from '@/hooks/use-chartdb';
import { cn } from '@/lib/utils';
@@ -30,7 +29,6 @@ export const Toolbar: React.FC<ToolbarProps> = () => {
const { redo, undo, hasRedo, hasUndo } = useHistory();
const { getZoom, zoomIn, zoomOut, fitView } = useReactFlow();
const [zoom, setZoom] = useState<string>(convertToPercentage(getZoom()));
const { isLostInCanvas } = useIsLostInCanvas();
const { setShowFilter } = useCanvas();
const { hiddenTableIds } = useChartDB();
@@ -106,14 +104,7 @@ export const Toolbar: React.FC<ToolbarProps> = () => {
<Tooltip>
<TooltipTrigger asChild>
<span>
<ToolbarButton
onClick={showAll}
className={
isLostInCanvas
? 'bg-pink-500 text-white hover:bg-pink-600 hover:text-white'
: ''
}
>
<ToolbarButton onClick={showAll}>
<Scan />
</ToolbarButton>
</span>