89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
|
|
import { useCallback, useState } from "react";
|
||
|
|
|
||
|
|
export type RightPanelMode = "view" | "edit" | "create";
|
||
|
|
export type RightPanelVisibility = "hidden" | "temporary" | "persistent";
|
||
|
|
|
||
|
|
export interface RightPanelStateOptions {
|
||
|
|
defaultMode?: RightPanelMode;
|
||
|
|
defaultVisibility?: RightPanelVisibility;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface RightPanelState {
|
||
|
|
mode: RightPanelMode;
|
||
|
|
visibility: RightPanelVisibility;
|
||
|
|
isOpen: boolean;
|
||
|
|
isPinned: boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface RightPanelStateActions {
|
||
|
|
onOpenChange: (next: boolean) => void;
|
||
|
|
openTemporary: (mode?: RightPanelMode) => void;
|
||
|
|
openPersistent: (mode?: RightPanelMode) => void;
|
||
|
|
togglePinned: () => void;
|
||
|
|
close: () => void;
|
||
|
|
reset: () => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
export type RightPanelStateController = RightPanelState & RightPanelStateActions;
|
||
|
|
|
||
|
|
const DEFAULT_MODE: RightPanelMode = "view";
|
||
|
|
const DEFAULT_VISIBILITY: RightPanelVisibility = "hidden";
|
||
|
|
|
||
|
|
export const useRightPanelState = (
|
||
|
|
options: RightPanelStateOptions = {}
|
||
|
|
): RightPanelStateController => {
|
||
|
|
const { defaultMode = DEFAULT_MODE, defaultVisibility = DEFAULT_VISIBILITY } = options;
|
||
|
|
|
||
|
|
const [mode, setMode] = useState<RightPanelMode>(defaultMode);
|
||
|
|
const [visibility, setVisibility] = useState<RightPanelVisibility>(defaultVisibility);
|
||
|
|
|
||
|
|
const isOpen = visibility !== "hidden";
|
||
|
|
const isPinned = visibility === "persistent";
|
||
|
|
|
||
|
|
const close = useCallback(() => {
|
||
|
|
setVisibility("hidden");
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const onOpenChange = useCallback((next: boolean) => {
|
||
|
|
setVisibility((prev) => {
|
||
|
|
if (!next) return "hidden";
|
||
|
|
return prev === "persistent" ? "persistent" : "temporary";
|
||
|
|
});
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const openTemporary = useCallback((nextMode: RightPanelMode = DEFAULT_MODE) => {
|
||
|
|
setMode(nextMode);
|
||
|
|
setVisibility("temporary");
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const openPersistent = useCallback((nextMode: RightPanelMode = DEFAULT_MODE) => {
|
||
|
|
setMode(nextMode);
|
||
|
|
setVisibility("persistent");
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const togglePinned = useCallback(() => {
|
||
|
|
setVisibility((prev) => {
|
||
|
|
if (prev === "hidden") return prev;
|
||
|
|
return prev === "persistent" ? "temporary" : "persistent";
|
||
|
|
});
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const reset = useCallback(() => {
|
||
|
|
setMode(defaultMode);
|
||
|
|
setVisibility(defaultVisibility);
|
||
|
|
}, [defaultMode, defaultVisibility]);
|
||
|
|
|
||
|
|
return {
|
||
|
|
mode,
|
||
|
|
visibility,
|
||
|
|
isOpen,
|
||
|
|
isPinned,
|
||
|
|
onOpenChange,
|
||
|
|
openTemporary,
|
||
|
|
openPersistent,
|
||
|
|
togglePinned,
|
||
|
|
close,
|
||
|
|
reset,
|
||
|
|
};
|
||
|
|
};
|