Files
automaker/apps/ui/src/components/layout/sidebar/hooks/use-theme-preview.ts
Kacper 7fac115a36 ♻️ refactor: extract Phase 1 hooks from sidebar (2187→2099 lines)
Extract 3 simple hooks with no UI dependencies:
- use-theme-preview.ts: Debounced theme preview on hover
- use-sidebar-auto-collapse.ts: Auto-collapse on small screens
- use-drag-and-drop.ts: Project reordering drag-and-drop

Benefits:
- Reduced sidebar.tsx by 88 lines (-4%)
- Improved testability (hooks can be tested in isolation)
- Removed unused imports (DragEndEvent, PointerSensor, useSensor, useSensors)
- Created hooks/ barrel export pattern

Next steps: Extract 10+ remaining hooks and 10+ UI sections to reach
target of 200-300 lines (current: 2099 lines, need to reduce ~1800 more)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 20:01:26 +01:00

54 lines
1.5 KiB
TypeScript

import { useRef, useCallback, useEffect } from 'react';
import type { ThemeMode } from '@/store/app-store';
interface UseThemePreviewProps {
setPreviewTheme: (theme: ThemeMode | null) => void;
}
export function useThemePreview({ setPreviewTheme }: UseThemePreviewProps) {
// Debounced preview theme handlers to prevent excessive re-renders
const previewTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const handlePreviewEnter = useCallback(
(value: string) => {
// Clear any pending timeout
if (previewTimeoutRef.current) {
clearTimeout(previewTimeoutRef.current);
}
// Small delay to debounce rapid hover changes
previewTimeoutRef.current = setTimeout(() => {
setPreviewTheme(value as ThemeMode);
}, 16); // ~1 frame delay
},
[setPreviewTheme]
);
const handlePreviewLeave = useCallback(
(e: React.PointerEvent) => {
const relatedTarget = e.relatedTarget as HTMLElement;
if (!relatedTarget?.closest('[data-testid^="project-theme-"]')) {
// Clear any pending timeout
if (previewTimeoutRef.current) {
clearTimeout(previewTimeoutRef.current);
}
setPreviewTheme(null);
}
},
[setPreviewTheme]
);
// Cleanup timeout on unmount
useEffect(() => {
return () => {
if (previewTimeoutRef.current) {
clearTimeout(previewTimeoutRef.current);
}
};
}, []);
return {
handlePreviewEnter,
handlePreviewLeave,
};
}