From 142523337b450103806a31ab64beedc35198edcd Mon Sep 17 00:00:00 2001 From: SaikaSakura Date: Thu, 28 Jul 2022 18:16:43 +0800 Subject: [PATCH] feat: grid item style --- .../src/blocks/grid-item/GridItem.tsx | 2 +- .../src/blocks/grid/GirdHandle.tsx | 37 ++++----- .../editor-blocks/src/blocks/grid/Grid.tsx | 6 +- libs/components/editor-core/src/Selection.tsx | 78 ++++++++++++------- .../src/editor/block/block-helper.ts | 4 + .../src/editor/selection/selection.ts | 15 +++- 6 files changed, 87 insertions(+), 55 deletions(-) diff --git a/libs/components/editor-blocks/src/blocks/grid-item/GridItem.tsx b/libs/components/editor-blocks/src/blocks/grid-item/GridItem.tsx index ae4f7581d2..491ac66628 100644 --- a/libs/components/editor-blocks/src/blocks/grid-item/GridItem.tsx +++ b/libs/components/editor-blocks/src/blocks/grid-item/GridItem.tsx @@ -124,7 +124,7 @@ export const GridItem: FC = function (props) { const GridItemContainer = styled('div')({ transition: 'background-color 0.3s ease-in-out', maxWidth: 'calc(100% - 10px)', - padding: '4px', + padding: '1px 3px', flexGrow: 1, border: '1px solid transparent', borderRadius: '4px', diff --git a/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx b/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx index aea646cbb0..af386ed0e8 100644 --- a/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx +++ b/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx @@ -3,6 +3,8 @@ import { useState } from 'react'; import { styled } from '@toeverything/components/ui'; import { BlockEditor } from '@toeverything/framework/virgo'; +const GRID_ADD_HANDLE_NAME = 'rid-add-handle'; + type GridHandleProps = { editor: BlockEditor; onDrag?: (e: MouseEvent) => void; @@ -56,7 +58,7 @@ export const GridHandle: FC = function ({ {enabledAddItem ? ( + @@ -70,14 +72,14 @@ const GridHandleContainer = styled('div')(({ theme }) => ({ width: '10px', flexGrow: '0', flexShrink: '0', - padding: '5px 4px', + padding: '5px 4.5px', minHeight: '15px', cursor: 'col-resize', borderRadius: '1px', backgroundClip: 'content-box', ' &:hover': { backgroundColor: theme.affine.palette.primary, - '.grid-add-handle': { + [`.${GRID_ADD_HANDLE_NAME}`]: { display: 'block', }, }, @@ -87,25 +89,18 @@ const AddGridHandle = styled('div')(({ theme }) => ({ display: 'none', position: 'absolute', transition: 'all 0.2s ease-in-out', - height: '6px', - width: '6px', - borderRadius: '6px', - top: '-6px', - left: '2px', - cursor: 'pointer', - backgroundColor: theme.affine.palette.menuSeparator, - color: theme.affine.palette.menuSeparator, - overflow: 'hidden', - fontWeight: 'bold', + height: '20px', lineHeight: '18px', + width: '10px', + borderRadius: '6px', + top: 'calc(50% - 10px)', + left: '0px', + cursor: 'pointer', + color: theme.affine.palette.primary, + overflow: 'hidden', textAlign: 'center', - ' &:hover': { - width: '20px', - height: '20px', - borderRadius: '10px', - backgroundColor: theme.affine.palette.primary, - color: theme.affine.palette.white, - top: '-20px', - left: '-5px', + backgroundColor: theme.affine.palette.white, + '&:hover': { + fontWeight: 'bold', }, })); diff --git a/libs/components/editor-blocks/src/blocks/grid/Grid.tsx b/libs/components/editor-blocks/src/blocks/grid/Grid.tsx index 16b0920a0d..daaddfba59 100644 --- a/libs/components/editor-blocks/src/blocks/grid/Grid.tsx +++ b/libs/components/editor-blocks/src/blocks/grid/Grid.tsx @@ -177,7 +177,7 @@ export const Grid: FC = function (props) { style={{ transition: isOnDrag ? 'none' - : 'width 0.2s ease-in-out', + : 'all 0.2s ease-in-out', }} key={id} className={GRID_ITEM_CLASS_NAME} @@ -218,9 +218,11 @@ const GridContainer = styled('div')({ position: 'relative', display: 'flex', alignItems: 'stretch', + borderRadius: '10px', + border: '1px solid #FFF', minWidth: `${GRID_ITEM_MIN_WIDTH}%`, [`&:hover .${GRID_ITEM_CONTENT_CLASS_NAME}`]: { - backgroundColor: 'rgba(100, 106, 115, 0.05)', + borderColor: '#E0E6EB', }, }); diff --git a/libs/components/editor-core/src/Selection.tsx b/libs/components/editor-core/src/Selection.tsx index 26880a9876..9d2a4c1d6c 100644 --- a/libs/components/editor-core/src/Selection.tsx +++ b/libs/components/editor-core/src/Selection.tsx @@ -16,11 +16,12 @@ interface SelectionProps { editor: BlockEditor; } -const RectContainer = styled('div')({ - backgroundColor: 'rgba(152, 172, 189, 0.1)', - position: 'absolute', - zIndex: 99, -}); +const DIRECTION_VALUE_MAP = { + right: -1, + left: 1, + down: -1, + up: 1, +} as const; type VerticalTypes = 'up' | 'down' | null; type HorizontalTypes = 'left' | 'right' | null; @@ -106,7 +107,7 @@ export const SelectionRect = forwardRef( const startPointRef = useRef(); const endPointRef = useRef(); const [rect, setRect] = useState(Rect.fromLTRB(0, 0, 0, 0)); - const startPointAtBlock = useRef(false); + const startPointBlock = useRef(); const mouseType = useRef('up'); const scrollContainerRect = useRef(); @@ -116,9 +117,12 @@ export const SelectionRect = forwardRef( ) => { await selectionManager.setSelectedNodesIds([]); startPointRef.current = new Point(event.clientX, event.clientY); - startPointAtBlock.current = - (await selectionManager.rootDomReady()) && - (await selectionManager.isPointInBlocks(startPointRef.current)); + startPointBlock.current = + ((await selectionManager.rootDomReady()) && + (await selectionManager.getBlockByPoint( + startPointRef.current + ))) || + null; mouseType.current = 'down'; if (scrollManager.scrollContainer) { scrollContainerRect.current = domToRect( @@ -130,11 +134,35 @@ export const SelectionRect = forwardRef( const onMouseMove = async ( event: React.MouseEvent ) => { - if (mouseType.current === 'down' && !startPointAtBlock.current) { - event.preventDefault(); + if (mouseType.current === 'down') { endPointRef.current = new Point(event.clientX, event.clientY); + if (startPointBlock.current) { + const endpointBlock = + await selectionManager.getBlockByPoint( + endPointRef.current + ); + // TODO: delete after multi-block text selection done + // if drag out of startblock change selection type to block + if (endpointBlock?.id === startPointBlock.current.id) { + return; + } + const selection = window.getSelection(); + if ( + selection && + selection.rangeCount > 0 && + editor.blockHelper.hasBlockTextUtils( + startPointBlock.current.id + ) + ) { + // slate will run hooks reset selection unless mouseup, + // remove slate selection by textUtils + editor.blockHelper.setBlockBlur( + startPointBlock.current.id + ); + } + event.preventDefault(); + } setShow(true); - if (startPointRef.current) { await setSelectedNodesByPoints( editor, @@ -177,7 +205,7 @@ export const SelectionRect = forwardRef( const onMouseUp = () => { mouseType.current = 'up'; - startPointAtBlock.current = false; + startPointBlock.current = null; setShow(false); scrollManager.stopAutoScroll(); }; @@ -200,24 +228,14 @@ export const SelectionRect = forwardRef( scrollManager.scrollContainer && scrollContainerRect.current ) { - const xValue = - direction[0] === 'right' - ? -1 - : direction[0] === 'left' - ? 1 - : 0; - const yValue = - direction[1] === 'down' - ? -1 - : direction[1] === 'up' - ? 1 - : 0; + const xSign = DIRECTION_VALUE_MAP[direction[0]] || 0; + const ySign = DIRECTION_VALUE_MAP[direction[1]] || 0; startPointRef.current = new Point( startPointRef.current.x + - xValue * scrollManager.scrollMoveOffset, + xSign * scrollManager.scrollMoveOffset, startPointRef.current.y + - yValue * scrollManager.scrollMoveOffset + ySign * scrollManager.scrollMoveOffset ); setSelectedNodesByPoints( @@ -260,3 +278,9 @@ export const SelectionRect = forwardRef( ) : null; } ); + +const RectContainer = styled('div')({ + backgroundColor: 'rgba(62, 111, 219, 0.1)', + position: 'absolute', + zIndex: 99, +}); diff --git a/libs/components/editor-core/src/editor/block/block-helper.ts b/libs/components/editor-core/src/editor/block/block-helper.ts index 1c1fafa99c..1c1ab37dbe 100644 --- a/libs/components/editor-core/src/editor/block/block-helper.ts +++ b/libs/components/editor-core/src/editor/block/block-helper.ts @@ -57,6 +57,10 @@ export class BlockHelper { delete this._blockTextUtilsMap[blockId]; } + public hasBlockTextUtils(blockId: string) { + return !!this._blockTextUtilsMap[blockId]; + } + /** * * get block serializer text by block id diff --git a/libs/components/editor-core/src/editor/selection/selection.ts b/libs/components/editor-core/src/editor/selection/selection.ts index 72ad0d9473..ab57513965 100644 --- a/libs/components/editor-core/src/editor/selection/selection.ts +++ b/libs/components/editor-core/src/editor/selection/selection.ts @@ -292,14 +292,22 @@ export class SelectionManager implements VirgoSelection { const rootBlock = await this._editor.getBlockById(rootBlockId); return Boolean(rootBlock?.dom); } - // TODO: Maybe just check root block - public async isPointInBlocks(point: Point) { + + public async getBlockByPoint(point: Point) { const blockList = await this._editor.getBlockList(); - return blockList.some(block => { + const outBlockList = blockList.filter(block => { return ( Boolean(block.dom) && domToRect(block.dom).isContainPoint(point) ); }); + + return outBlockList.length + ? outBlockList[outBlockList.length - 1] + : undefined; + } + + public async isPointInBlocks(point: Point) { + return Boolean(this.getBlockByPoint(point)); } /** @@ -362,7 +370,6 @@ export class SelectionManager implements VirgoSelection { } } } - console.log({ selectedNodes }); return selectedNodes; }