import {ReactNode, useCallback} from 'react';
import styled from '@emotion/styled';
import debounce from 'lodash/debounce';
import useSplitPanelTracking from 'sentry/utils/replays/hooks/useSplitPanelTracking';
import {useResizableDrawer} from 'sentry/utils/useResizableDrawer';
import SplitDivider from 'sentry/views/replays/detail/layout/splitDivider';
type Side = {
content: ReactNode;
default: number;
max: number;
min: number;
};
type Props =
| {
availableSize: number;
/**
* Content on the right side of the split
*/
left: Side;
/**
* Content on the left side of the split
*/
right: ReactNode;
}
| {
availableSize: number;
/**
* Content below the split
*/
bottom: ReactNode;
/**
* Content above of the split
*/
top: Side;
};
function SplitPanel(props: Props) {
const isLeftRight = 'left' in props;
const initialSize = isLeftRight ? props.left.default : props.top.default;
const min = isLeftRight ? props.left.min : props.top.min;
const max = isLeftRight ? props.left.max : props.top.max;
const {setStartPosition, logEndPosition} = useSplitPanelTracking({
slideDirection: isLeftRight ? 'leftright' : 'updown',
});
// eslint-disable-next-line react-hooks/exhaustive-deps
const onResize = useCallback(
debounce(newSize => logEndPosition(`${(newSize / props.availableSize) * 100}%`), 750),
[debounce, logEndPosition, props.availableSize]
);
const {
isHeld,
onDoubleClick,
onMouseDown: onDragStart,
size: containerSize,
} = useResizableDrawer({
direction: isLeftRight ? 'left' : 'down',
initialSize,
min,
onResize,
});
const sizePct = `${
(Math.min(containerSize, max) / props.availableSize) * 100
}%` as `${number}%`;
const handleMouseDown = useCallback(
event => {
setStartPosition(sizePct);
onDragStart(event);
},
[setStartPosition, onDragStart, sizePct]
);
if (isLeftRight) {
const {left: a, right: b} = props;
return (
{a.content}
{b}
);
}
const {top: a, bottom: b} = props;
return (
{a.content}
{b}
);
}
const SplitPanelContainer = styled('div')<{
orientation: 'rows' | 'columns';
size: `${number}px` | `${number}%`;
}>`
width: 100%;
height: 100%;
position: relative;
display: grid;
overflow: auto;
grid-template-${p => p.orientation}: ${p => p.size} auto 1fr;
&.disable-iframe-pointer iframe {
pointer-events: none !important;
}
`;
const Panel = styled('div')`
overflow: hidden;
`;
export default SplitPanel;