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 | 1x 30x 30x 30x 1x | import React, { forwardRef } from "react";
import { clsx } from "clsx";
import type { PanelPosition } from "../../types";
import { Z_INDEX } from "../../constants";
import styles from "./Panel.module.scss";
export interface PanelProps {
/** Whether the panel is open */
isOpen: boolean;
/** Position of the panel */
position?: PanelPosition;
/** Panel width in pixels */
width?: number;
/** Z-index for the panel */
zIndex?: number;
/** Whether to show backdrop overlay */
showBackdrop?: boolean;
/** Callback when backdrop is clicked */
onBackdropClick?: () => void;
/** Custom class name */
className?: string;
/** Dark mode */
isDark?: boolean;
/** Panel content */
children: React.ReactNode;
}
/**
* Slide-in panel container component
* Uses position: fixed for viewport-relative positioning
*/
export const Panel = forwardRef<HTMLDivElement, PanelProps>(
(
{
isOpen,
position = "right",
width = 400,
zIndex = Z_INDEX.panel,
showBackdrop = false,
onBackdropClick,
className,
isDark = false,
children,
},
ref
) => {
const positionClass = position === "right" ? styles.positionRight : styles.positionLeft;
const closedClass = position === "right" ? styles.closedRight : styles.closedLeft;
return (
<>
{/* Backdrop */}
{showBackdrop && (
<div
className={clsx(
styles.backdrop,
isOpen ? styles.open : styles.closed
)}
style={{ zIndex: zIndex - 1 }}
onClick={onBackdropClick}
aria-hidden="true"
/>
)}
{/* Panel */}
<div
ref={ref}
role="dialog"
aria-label="Memory Monitor Panel"
aria-modal={showBackdrop}
aria-hidden={!isOpen}
data-position={position}
className={clsx(
styles.panel,
positionClass,
isOpen ? styles.open : closedClass,
isDark && "dark",
className
)}
style={{
width: `${width}px`,
zIndex,
}}
>
{/* Inner wrapper with theme-aware styles */}
<div className={clsx(styles.panelInner, isDark && styles.panelInnerDark)}>
{children}
</div>
</div>
</>
);
}
);
Panel.displayName = "Panel";
|