From 28a6c46605d393cf058e8ac6a17dd2350f979581 Mon Sep 17 00:00:00 2001 From: Qi <474021214@qq.com> Date: Fri, 24 Feb 2023 02:32:02 +0800 Subject: [PATCH] feat: support sidebar zoom (#1190) --- .../workspace-slider-bar/DragLine.tsx | 92 +++++++++++++++++++ .../components/workspace-slider-bar/index.tsx | 16 +++- .../components/workspace-slider-bar/style.ts | 34 +++---- 3 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 apps/web/src/components/workspace-slider-bar/DragLine.tsx diff --git a/apps/web/src/components/workspace-slider-bar/DragLine.tsx b/apps/web/src/components/workspace-slider-bar/DragLine.tsx new file mode 100644 index 0000000000..a8011b2d44 --- /dev/null +++ b/apps/web/src/components/workspace-slider-bar/DragLine.tsx @@ -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(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 ( + { + 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'); + }} + > + ); +}; + +export default DragLine; diff --git a/apps/web/src/components/workspace-slider-bar/index.tsx b/apps/web/src/components/workspace-slider-bar/index.tsx index 3121e64fe3..f45a71de58 100644 --- a/apps/web/src/components/workspace-slider-bar/index.tsx +++ b/apps/web/src/components/workspace-slider-bar/index.tsx @@ -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 ( <> - + + {show && ( + { + setSideBarWidth(sideBarWidth + movementX); + }} + /> + )} ( - ({ 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%',