You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailchat/web/src/routes/Main/Content/PageContent.tsx

119 lines
3.0 KiB
TypeScript

import React, { useCallback } from 'react';
import { useSidebarContext } from '../SidebarContext';
import _isNil from 'lodash/isNil';
import { useDrag } from 'react-use-gesture';
import { useIsMobile } from '@/hooks/useIsMobile';
import clsx from 'clsx';
// const ContentDetail = styled.div`
// flex: 1;
// background-color: ${(props) => props.theme.style.contentBackgroundColor};
// display: flex;
// flex-direction: column;
// position: relative;
// overflow: hidden;
// @media (max-width: 768px) {
// width: ${(props) => `calc(100vw - ${props.theme.style.navbarWidth})`};
// min-width: ${(props) => `calc(100vw - ${props.theme.style.navbarWidth})`};
// }
// `;
// const SidebarContainer = styled.div<{
// showSidebar: boolean;
// }>`
// ${(props) => props.theme.mixins.transition('width', 0.2)};
// width: ${(props) => (props.showSidebar ? props.theme.style.sidebarWidth : 0)};
// background-color: ${(props) => props.theme.style.sidebarBackgroundColor};
// overflow: hidden;
// display: flex;
// flex-direction: column;
// flex: none;
// `;
const PageContentRoot: React.FC = (props) => (
<div className="flex flex-row flex-1 overflow-hidden">{props.children}</div>
);
interface PageContentProps {
sidebar?: React.ReactNode;
}
const PageGestureWrapper: React.FC = React.memo((props) => {
const { setShowSidebar } = useSidebarContext();
const bind = useDrag(
(state) => {
const { swipe } = state;
const swipeX = swipe[0];
if (swipeX > 0) {
setShowSidebar(true);
} else if (swipeX < 0) {
setShowSidebar(false);
}
},
{
axis: 'x',
swipeDistance: 5,
}
);
return <PageContentRoot {...bind()}>{props.children}</PageContentRoot>;
});
PageGestureWrapper.displayName = 'PageGestureWrapper';
/**
*
*
* TODO:
*/
export const PageContent: React.FC<PageContentProps> = React.memo((props) => {
const { sidebar, children } = props;
const { showSidebar, setShowSidebar } = useSidebarContext();
const isMobile = useIsMobile();
const handleHideSidebar = useCallback(() => {
setShowSidebar(false);
}, []);
const sidebarEl = _isNil(sidebar) ? null : (
<div
className={clsx('bg-gray-800 p-2', {
'w-60': showSidebar,
})}
>
{props.sidebar}
</div>
);
// 是否显示遮罩层
const showMask =
isMobile === true && showSidebar === true && !_isNil(sidebarEl);
const contentMaskEl = showMask ? (
<div
className="absolute left-0 top-0 bottom-0 right-0 z-10"
onClick={handleHideSidebar}
/>
) : null;
const contentEl = children;
const el = (
<>
{sidebarEl}
<div className="flex flex-auto bg-gray-700 relative">
{contentMaskEl}
{contentEl}
</div>
</>
);
if (isMobile) {
return <PageGestureWrapper>{el}</PageGestureWrapper>;
} else {
return <PageContentRoot>{el}</PageContentRoot>;
}
});
PageContent.displayName = 'PageContent';