mirror of
https://github.com/chartdb/chartdb.git
synced 2026-01-07 20:30:00 -06:00
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:
@@ -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"
|
||||
|
||||
65
src/pages/editor-page/canvas/show-all-button.tsx
Normal file
65
src/pages/editor-page/canvas/show-all-button.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user