import { m } from "framer-motion"; import { observer } from "mobx-react"; import * as React from "react"; import styled, { useTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; import Flex from "~/components/Flex"; import ResizeBorder from "~/components/Sidebar/components/ResizeBorder"; import usePersistedState from "~/hooks/usePersistedState"; type Props = React.HTMLAttributes & { children: React.ReactNode; border?: boolean; }; function Right({ children, border, className }: Props) { const theme = useTheme(); const [width, setWidth] = usePersistedState( "rightSidebarWidth", theme.sidebarWidth ); const [isResizing, setResizing] = React.useState(false); const maxWidth = theme.sidebarMaxWidth; const minWidth = theme.sidebarMinWidth + 16; // padding const handleDrag = React.useCallback( (event: MouseEvent) => { // suppresses text selection event.preventDefault(); const width = Math.max( Math.min(window.innerWidth - event.pageX, maxWidth), minWidth ); setWidth(width); }, [minWidth, maxWidth, setWidth] ); const handleReset = React.useCallback(() => { setWidth(theme.sidebarWidth); }, [setWidth, theme.sidebarWidth]); const handleStopDrag = React.useCallback(() => { setResizing(false); if (document.activeElement) { // @ts-expect-error ts-migrate(2339) FIXME: Property 'blur' does not exist on type 'Element'. document.activeElement.blur(); } }, []); const handleMouseDown = React.useCallback(() => { setResizing(true); }, []); React.useEffect(() => { if (isResizing) { document.addEventListener("mousemove", handleDrag); document.addEventListener("mouseup", handleStopDrag); } return () => { document.removeEventListener("mousemove", handleDrag); document.removeEventListener("mouseup", handleStopDrag); }; }, [isResizing, handleDrag, handleStopDrag]); const style = React.useMemo( () => ({ width: `${width}px`, }), [width] ); return ( {children} ); } const Position = styled(Flex)` position: fixed; top: 0; bottom: 0; `; const Sidebar = styled(m.div)<{ $border?: boolean }>` display: none; position: relative; flex-shrink: 0; background: ${(props) => props.theme.background}; width: ${(props) => props.theme.sidebarWidth}px; border-left: 1px solid ${(props) => props.theme.divider}; transition: border-left 100ms ease-in-out; z-index: 1; ${breakpoint("tablet")` display: flex; `}; `; export default observer(Right);