Files
twenty/packages/twenty-front/src/modules/command-menu/components/CommandMenuWidthEffect.tsx
T
Félix Malfait 4fe8e3d3b6 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`
2025-12-18 09:09:21 +01:00

21 lines
474 B
TypeScript

import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import {
COMMAND_MENU_WIDTH_VAR,
commandMenuWidthState,
} from '../states/commandMenuWidthState';
export const CommandMenuWidthEffect = () => {
const commandMenuWidth = useRecoilValue(commandMenuWidthState);
useEffect(() => {
document.documentElement.style.setProperty(
COMMAND_MENU_WIDTH_VAR,
`${commandMenuWidth}px`,
);
}, [commandMenuWidth]);
return null;
};