feat: support sidebar zoom (#1190)

This commit is contained in:
Qi
2023-02-24 02:32:02 +08:00
committed by GitHub
parent d84b47f226
commit 28a6c46605
3 changed files with 125 additions and 17 deletions

View File

@@ -0,0 +1,92 @@
import { styled } from '@affine/component';
import React, { useEffect, useRef } from 'react';
const StyledDragLine = styled.div(({ theme }) => {
return {
width: '5px',
height: '100%',
position: 'absolute',
top: '0',
right: '-10px',
cursor: 'col-resize',
};
});
export type DragLineProps = {
onDrag?: (params: { movementX: number; movementY: number }) => void;
initialPosition?: { x: number; y: number };
leftOffset?: number;
rightOffset?: number;
};
export const DragLine = ({
onDrag,
leftOffset,
rightOffset,
initialPosition,
}: DragLineProps) => {
const isDragging = useRef(false);
const lineRef = useRef<HTMLDivElement>(null);
const recordPosition = useRef({ x: 0, y: 0 });
useEffect(() => {
const onMouseMove = (e: MouseEvent) => {
if (!isDragging.current) return;
const movementX = e.clientX - recordPosition.current.x;
const movementY = e.clientY - recordPosition.current.y;
if (
(rightOffset !== undefined &&
initialPosition &&
initialPosition.x + rightOffset < recordPosition.current.x) ||
(leftOffset !== undefined &&
initialPosition &&
recordPosition.current.x - initialPosition.x < leftOffset)
) {
recordPosition.current.x = e.clientX;
recordPosition.current.y = e.clientY;
document.body.style.cursor = 'not-allowed';
return;
}
document.body.style.cursor = 'col-resize';
onDrag?.({ movementX, movementY });
recordPosition.current.x = e.clientX;
recordPosition.current.y = e.clientY;
};
const onMouseUp = () => {
isDragging.current = false;
document.body.style.cursor = '';
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
return () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
}, [initialPosition, leftOffset, onDrag, rightOffset]);
return (
<StyledDragLine
ref={lineRef}
//The mouse event is used instead of the drag event because the drag event triggers the drag image display
onMouseDown={e => {
e.preventDefault();
isDragging.current = true;
const position = lineRef.current?.getBoundingClientRect();
recordPosition.current = {
x: position?.x || 0,
y: position?.y || 0,
};
}}
onMouseUp={() => {
isDragging.current = false;
console.log('onMouseUp');
}}
></StyledDragLine>
);
};
export default DragLine;

View File

@@ -20,6 +20,7 @@ import { usePageHelper } from '@/hooks/use-page-helper';
import { useGlobalState } from '@/store/app';
import { useModal } from '@/store/globalModal';
import StyledDragLine from './DragLine';
import { Arrow } from './icons';
import {
StyledArrowButton,
@@ -32,6 +33,8 @@ import {
} from './style';
import { WorkspaceSelector } from './WorkspaceSelector/WorkspaceSelector';
const MAX_WIDTH = 534;
const MIN_WIDTH = 256;
const FavoriteList = ({ showList }: { showList: boolean }) => {
const { openPage } = usePageHelper();
const pageList = useGlobalState(store => store.dataCenterPageList);
@@ -67,6 +70,7 @@ const FavoriteList = ({ showList }: { showList: boolean }) => {
export const WorkSpaceSliderBar = () => {
const { triggerQuickSearchModal } = useModal();
const [showSubFavorite, setShowSubFavorite] = useState(true);
const [sideBarWidth, setSideBarWidth] = useState(256);
const currentWorkspace = useGlobalState(
useCallback(store => store.currentDataCenterWorkspace, [])
);
@@ -88,7 +92,17 @@ export const WorkSpaceSliderBar = () => {
};
return (
<>
<StyledSliderBar show={show}>
<StyledSliderBar show={show} width={sideBarWidth}>
{show && (
<StyledDragLine
initialPosition={{ x: MIN_WIDTH, y: 0 }}
rightOffset={MAX_WIDTH - MIN_WIDTH}
leftOffset={0}
onDrag={({ movementX }) => {
setSideBarWidth(sideBarWidth + movementX);
}}
/>
)}
<Tooltip
content={show ? t('Collapse sidebar') : t('Expand sidebar')}
placement="right"

View File

@@ -1,22 +1,24 @@
import { displayFlex, styled, textEllipsis } from '@affine/component';
import Link from 'next/link';
import { CSSProperties } from 'react';
export const StyledSliderBar = styled.div<{ show: boolean }>(
({ theme, show }) => {
return {
width: show ? '256px' : '0',
height: '100vh',
minHeight: '450px',
background: theme.colors.hubBackground,
boxShadow: theme.shadow.modal,
transition: 'width .15s, padding .15s',
position: 'relative',
zIndex: theme.zIndex.modal,
padding: show ? '24px 12px' : '24px 0',
flexShrink: 0,
};
}
);
export const StyledSliderBar = styled.div<{
show: boolean;
width: CSSProperties['width'];
}>(({ theme, show, width }) => {
return {
width: show ? width : '0',
height: '100vh',
minHeight: '450px',
background: theme.colors.hubBackground,
boxShadow: theme.shadow.modal,
transition: 'width .15s, padding .15s',
position: 'relative',
zIndex: theme.zIndex.modal,
padding: show ? '24px 12px' : '24px 0',
flexShrink: 0,
};
});
export const StyledSliderBarWrapper = styled.div(() => {
return {
height: '100%',