Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 64x 64x 64x 64x 3x 3x 3x 3x 64x 4x 4x 4x 4x 64x 3x 3x 3x 64x 64x 64x | import { useState, useCallback } from "react";
import type { PanelTab, PanelState } from "../types";
/**
* Options for usePanelState hook
*/
export interface UsePanelStateOptions {
/** Initial open state */
defaultOpen?: boolean;
/** Initial active tab */
defaultTab?: PanelTab;
/** Callback when open state changes */
onOpenChange?: (open: boolean) => void;
}
/**
* Return type for usePanelState hook
*/
export interface UsePanelStateReturn {
/** Current panel state */
state: PanelState;
/** Whether the panel is open */
isOpen: boolean;
/** Currently active tab */
activeTab: PanelTab;
/** List of expanded section IDs */
expandedSections: string[];
/** Open the panel */
open: () => void;
/** Close the panel */
close: () => void;
/** Toggle the panel open/closed */
toggle: () => void;
/** Set the active tab */
setActiveTab: (tab: PanelTab) => void;
/** Toggle a section's expanded state */
toggleSection: (sectionId: string) => void;
/** Check if a section is expanded */
isSectionExpanded: (sectionId: string) => boolean;
}
/**
* Hook to manage panel UI state
*
* @param options - Configuration options
* @returns Panel state and control functions
*
* @example
* ```tsx
* const { isOpen, toggle, activeTab, setActiveTab } = usePanelState({
* defaultOpen: false,
* defaultTab: 'overview',
* });
* ```
*/
export function usePanelState(
options: UsePanelStateOptions = {}
): UsePanelStateReturn {
const { defaultOpen = false, defaultTab = "overview", onOpenChange } = options;
const [state, setState] = useState<PanelState>({
isOpen: defaultOpen,
activeTab: defaultTab,
expandedSections: ["memory", "status", "actions"], // Default expanded sections
});
const open = useCallback(() => {
setState((prev) => {
if (prev.isOpen) return prev;
onOpenChange?.(true);
return { ...prev, isOpen: true };
});
}, [onOpenChange]);
const close = useCallback(() => {
setState((prev) => {
Iif (!prev.isOpen) return prev;
onOpenChange?.(false);
return { ...prev, isOpen: false };
});
}, [onOpenChange]);
const toggle = useCallback(() => {
setState((prev) => {
const nextOpen = !prev.isOpen;
onOpenChange?.(nextOpen);
return { ...prev, isOpen: nextOpen };
});
}, [onOpenChange]);
const setActiveTab = useCallback((tab: PanelTab) => {
setState((prev) => {
Iif (prev.activeTab === tab) return prev;
return { ...prev, activeTab: tab };
});
}, []);
const toggleSection = useCallback((sectionId: string) => {
setState((prev) => {
const isExpanded = prev.expandedSections.includes(sectionId);
return {
...prev,
expandedSections: isExpanded
? prev.expandedSections.filter((id) => id !== sectionId)
: [...prev.expandedSections, sectionId],
};
});
}, []);
const isSectionExpanded = useCallback(
(sectionId: string) => {
return state.expandedSections.includes(sectionId);
},
[state.expandedSections]
);
return {
state,
isOpen: state.isOpen,
activeTab: state.activeTab,
expandedSections: state.expandedSections,
open,
close,
toggle,
setActiveTab,
toggleSection,
isSectionExpanded,
};
}
|