59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import { memo, type ReactNode } from "react";
|
|
|
|
import { ChatNatalChart } from "@/components/chat-natal-chart";
|
|
import { Button } from "@/components/ui/button";
|
|
import { useDragWidth } from "@/hooks/use-drag-width";
|
|
import { CHAT_CHART_WIDTH_MAX, CHAT_CHART_WIDTH_MIN } from "@/lib/chat-chart-panel-state";
|
|
|
|
/**
|
|
* The right-hand natal column. The chat column stays outside it, so loading this
|
|
* never remounts the chat (BUG-1448). Its left edge drags or takes the arrow
|
|
* keys; dragging below the minimum closes the panel (BUG-1456). Memoized: its
|
|
* props are store values, so a Home render alone never redraws the chart (issue #123).
|
|
* `switcher` (issue #150) is a fresh element on every Home render, so the drawing
|
|
* sits behind its own memo and only the switcher repaints.
|
|
*/
|
|
const StableNatalChart = memo(ChatNatalChart);
|
|
|
|
export const ChatChartSplit = memo(function ChatChartSplit({
|
|
open,
|
|
width,
|
|
subjectId,
|
|
switcher,
|
|
onOpenChange,
|
|
onWidth,
|
|
}: {
|
|
open: boolean;
|
|
width: number;
|
|
subjectId: string;
|
|
switcher?: ReactNode;
|
|
onOpenChange: (open: boolean) => void;
|
|
onWidth: (width: number) => void;
|
|
}) {
|
|
const resize = useDragWidth({
|
|
width,
|
|
min: CHAT_CHART_WIDTH_MIN,
|
|
max: CHAT_CHART_WIDTH_MAX,
|
|
edge: "left",
|
|
onWidth,
|
|
onCollapse: () => onOpenChange(false),
|
|
});
|
|
|
|
if (!open) return null;
|
|
return (
|
|
<aside className="chat-chart-split" style={{ width }} aria-label="本命盘">
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
className="chat-chart-resize-handle"
|
|
aria-label="调整本命盘宽度"
|
|
{...resize}
|
|
/>
|
|
{switcher ? <div className="chat-chart-switcher">{switcher}</div> : null}
|
|
<StableNatalChart subjectId={subjectId} />
|
|
</aside>
|
|
);
|
|
});
|