feat: add resizable navigation drawer and command menu panels (#16612)
## Summary Adds Notion-style resizable panels for the navigation drawer (left sidebar) and command menu (right panel). ## Behavior - **Hover** at panel edge → resize cursor appears - **Click** → collapse/close the panel - **Drag** → resize the panel (5px movement threshold to distinguish from click) ## Constraints | Panel | Min | Max | Default | Collapse Threshold | |-------|-----|-----|---------|-------------------| | Navigation Drawer | 180px | 350px | 220px | 150px | | Command Menu | 320px | 600px | 400px | 250px | ## Performance Optimizations - **CSS variables** for smooth 60fps resize (no React re-renders during drag) - **Table resize observer disabled** during panel resize to prevent expensive recalculations - **React.memo wrapper** on page body to prevent unnecessary re-renders ## Architecture - `useResizablePanel` hook following the same pattern as `useResizeTableHeader` - `ResizablePanelEdge` - resize handle positioned at panel edge - `ResizablePanelGap` - resize handle in the gap between panels - `cssVariableEffect` - Recoil effect to sync CSS variables with state ## Refactoring - Split `recoil-effects.ts` into separate files in `utils/recoil/` (one export per file) - Persist panel widths to localStorage via existing `localStorageEffect`
This commit is contained in:
+9
-6
@@ -1,5 +1,5 @@
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { COMMAND_MENU_SIDE_PANEL_WIDTH } from '@/command-menu/constants/CommandMenuSidePanelWidth';
|
||||
import { commandMenuWidthState } from '@/command-menu/states/commandMenuWidthState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { useListenToSidePanelClosing } from '@/ui/layout/right-drawer/hooks/useListenToSidePanelClosing';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
@@ -222,7 +222,7 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const setFlowViewport = useRecoilCallback(
|
||||
() =>
|
||||
({ snapshot }) =>
|
||||
({
|
||||
workflowDiagramFlowInitialized,
|
||||
isCommandMenuOpened,
|
||||
@@ -260,12 +260,15 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
|
||||
let adjustedContainerWidth = baseContainerWidth;
|
||||
|
||||
const commandMenuWidth = getSnapshotValue(
|
||||
snapshot,
|
||||
commandMenuWidthState,
|
||||
);
|
||||
|
||||
if (!isInRightDrawer && isCommandMenuOpened) {
|
||||
adjustedContainerWidth =
|
||||
baseContainerWidth - COMMAND_MENU_SIDE_PANEL_WIDTH;
|
||||
adjustedContainerWidth = baseContainerWidth - commandMenuWidth;
|
||||
} else if (!isInRightDrawer && hasViewportBeenMoved) {
|
||||
adjustedContainerWidth =
|
||||
baseContainerWidth + COMMAND_MENU_SIDE_PANEL_WIDTH;
|
||||
adjustedContainerWidth = baseContainerWidth + commandMenuWidth;
|
||||
}
|
||||
|
||||
const flowBounds = reactflow.getNodesBounds(nodes);
|
||||
|
||||
Reference in New Issue
Block a user