mirror of
https://github.com/JOYCEQL/magic-resume.git
synced 2026-07-03 14:07:11 +02:00
perf: layout config
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, memo } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { Eye, Edit2, Menu, PanelLeft, Minimize2 } from "lucide-react";
|
||||
import { EditorHeader } from "@/components/editor/EditorHeader";
|
||||
@@ -22,12 +22,12 @@ import {
|
||||
} from "@/components/ui/tooltip";
|
||||
|
||||
const LAYOUT_CONFIG = {
|
||||
DEFAULT: [18, 32, 50],
|
||||
SIDE_COLLAPSED: [0, 50, 50],
|
||||
EDIT_FOCUSED_WITH_SIDE: [0, 100, 0],
|
||||
PREVIEW_FOCUSED_WITH_SIDE: [0, 0, 100],
|
||||
EDIT_FOCUSED_NO_SIDE: [0, 100, 0],
|
||||
PREVIEW_FOCUSED_NO_SIDE: [0, 0, 100],
|
||||
DEFAULT: [20, 32, 48],
|
||||
SIDE_COLLAPSED: [50, 50],
|
||||
EDIT_FOCUSED_WITH_SIDE: [18, 82, 0],
|
||||
PREVIEW_FOCUSED_WITH_SIDE: [18, 0, 82],
|
||||
EDIT_FOCUSED_NO_SIDE: [100, 0],
|
||||
PREVIEW_FOCUSED_NO_SIDE: [0, 100],
|
||||
};
|
||||
|
||||
const DragHandle = ({ show = true }) => {
|
||||
@@ -56,53 +56,18 @@ const DragHandle = ({ show = true }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
const [sidePanelCollapsed, setSidePanelCollapsed] = useState(false);
|
||||
const [focusedPanel, setFocusedPanel] = useState<null | "edit" | "preview">(
|
||||
null
|
||||
);
|
||||
const [showMobileSidebar, setShowMobileSidebar] = useState(false);
|
||||
const [isMobilePreview, setIsMobilePreview] = useState(false);
|
||||
const [panelSizes, setPanelSizes] = useState(LAYOUT_CONFIG.DEFAULT);
|
||||
const [layoutKey, setLayoutKey] = useState(0);
|
||||
|
||||
const updateLayout = (newSizes: number[]) => {
|
||||
setPanelSizes(newSizes);
|
||||
setLayoutKey((prev) => prev + 1);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let newSizes;
|
||||
if (sidePanelCollapsed) {
|
||||
if (focusedPanel === "edit") {
|
||||
newSizes = [...LAYOUT_CONFIG.EDIT_FOCUSED_NO_SIDE];
|
||||
} else if (focusedPanel === "preview") {
|
||||
newSizes = [...LAYOUT_CONFIG.PREVIEW_FOCUSED_NO_SIDE];
|
||||
} else {
|
||||
newSizes = [...LAYOUT_CONFIG.SIDE_COLLAPSED];
|
||||
}
|
||||
} else {
|
||||
if (focusedPanel === "edit") {
|
||||
newSizes = [...LAYOUT_CONFIG.EDIT_FOCUSED_WITH_SIDE];
|
||||
} else if (focusedPanel === "preview") {
|
||||
newSizes = [...LAYOUT_CONFIG.PREVIEW_FOCUSED_WITH_SIDE];
|
||||
} else {
|
||||
newSizes = [...LAYOUT_CONFIG.DEFAULT];
|
||||
}
|
||||
}
|
||||
updateLayout([...newSizes]);
|
||||
}, [sidePanelCollapsed, focusedPanel]);
|
||||
|
||||
const toggleSidePanel = () => {
|
||||
setSidePanelCollapsed(!sidePanelCollapsed);
|
||||
};
|
||||
|
||||
const togglePanelFocus = (panel: "edit" | "preview") => {
|
||||
setFocusedPanel(focusedPanel === panel ? null : panel);
|
||||
};
|
||||
|
||||
// 底部控制栏
|
||||
const LayoutControls = () => (
|
||||
const LayoutControls = memo(
|
||||
({
|
||||
sidePanelCollapsed,
|
||||
focusedPanel,
|
||||
toggleSidePanel,
|
||||
togglePanelFocus,
|
||||
}: {
|
||||
sidePanelCollapsed: boolean;
|
||||
focusedPanel: null | "edit" | "preview";
|
||||
toggleSidePanel: () => void;
|
||||
togglePanelFocus: (panel: "edit" | "preview") => void;
|
||||
}) => (
|
||||
<div
|
||||
className={cn(
|
||||
"absolute bottom-6 left-1/2 -translate-x-1/2",
|
||||
@@ -181,8 +146,57 @@ export default function Home() {
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
LayoutControls.displayName = "LayoutControls";
|
||||
|
||||
export default function Home() {
|
||||
const [sidePanelCollapsed, setSidePanelCollapsed] = useState(false);
|
||||
const [focusedPanel, setFocusedPanel] = useState<null | "edit" | "preview">(
|
||||
null
|
||||
);
|
||||
|
||||
const [showMobileSidebar, setShowMobileSidebar] = useState(false);
|
||||
const [isMobilePreview, setIsMobilePreview] = useState(false);
|
||||
const [panelSizes, setPanelSizes] = useState(LAYOUT_CONFIG.DEFAULT);
|
||||
const [layoutKey, setLayoutKey] = useState(0);
|
||||
|
||||
const updateLayout = (newSizes: number[]) => {
|
||||
setPanelSizes(newSizes);
|
||||
setLayoutKey((prev) => prev + 1);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let newSizes;
|
||||
if (sidePanelCollapsed) {
|
||||
if (focusedPanel === "edit") {
|
||||
newSizes = [100, 0];
|
||||
} else if (focusedPanel === "preview") {
|
||||
newSizes = [0, 100];
|
||||
} else {
|
||||
newSizes = [50, 50];
|
||||
}
|
||||
} else {
|
||||
if (focusedPanel === "edit") {
|
||||
newSizes = [18, 82, 0];
|
||||
} else if (focusedPanel === "preview") {
|
||||
newSizes = [18, 0, 82];
|
||||
} else {
|
||||
newSizes = [20, 32, 48];
|
||||
}
|
||||
}
|
||||
updateLayout([...newSizes]);
|
||||
}, [sidePanelCollapsed, focusedPanel]);
|
||||
|
||||
const toggleSidePanel = () => {
|
||||
setSidePanelCollapsed(!sidePanelCollapsed);
|
||||
};
|
||||
|
||||
const togglePanelFocus = (panel: "edit" | "preview") => {
|
||||
setFocusedPanel(focusedPanel === panel ? null : panel);
|
||||
};
|
||||
|
||||
// 移动端控制栏
|
||||
const MobileControls = () => (
|
||||
<div
|
||||
@@ -275,6 +289,8 @@ export default function Home() {
|
||||
{!sidePanelCollapsed && (
|
||||
<>
|
||||
<ResizablePanel
|
||||
id="side-panel"
|
||||
order={1}
|
||||
defaultSize={panelSizes[0]}
|
||||
minSize={18}
|
||||
className={cn(
|
||||
@@ -291,6 +307,8 @@ export default function Home() {
|
||||
|
||||
{/* 编辑面板 */}
|
||||
<ResizablePanel
|
||||
id="edit-panel"
|
||||
order={2}
|
||||
defaultSize={panelSizes[1]}
|
||||
className={cn(
|
||||
"dark:bg-neutral-900 dark:border-r dark:border-neutral-800"
|
||||
@@ -300,11 +318,14 @@ export default function Home() {
|
||||
<EditPanel />
|
||||
</div>
|
||||
</ResizablePanel>
|
||||
{/* <DragHandle /> */}
|
||||
<DragHandle />
|
||||
{/* 预览面板 */}
|
||||
<ResizablePanel
|
||||
id="preview-panel"
|
||||
order={3}
|
||||
minSize={48}
|
||||
collapsible={false}
|
||||
defaultSize={panelSizes[2]}
|
||||
defaultSize={panelSizes ? panelSizes[2] : LAYOUT_CONFIG.DEFAULT[2]}
|
||||
className="bg-gray-100"
|
||||
>
|
||||
<div className="h-full overflow-y-auto">
|
||||
@@ -313,7 +334,12 @@ export default function Home() {
|
||||
</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
|
||||
<LayoutControls />
|
||||
<LayoutControls
|
||||
sidePanelCollapsed={sidePanelCollapsed}
|
||||
focusedPanel={focusedPanel}
|
||||
toggleSidePanel={toggleSidePanel}
|
||||
togglePanelFocus={togglePanelFocus}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 移动端布局 */}
|
||||
|
||||
@@ -132,7 +132,7 @@ const PreviewPanel = () => {
|
||||
<div
|
||||
ref={startRef}
|
||||
className={cn(
|
||||
"w-[210mm] min-h-[297mm]",
|
||||
"w-[210mm] min-w-[210mm] min-h-[297mm]",
|
||||
"bg-white",
|
||||
"shadow-lg",
|
||||
"relative mx-auto"
|
||||
|
||||
Reference in New Issue
Block a user