fix(select): select rect position
This commit is contained in:
@@ -4,7 +4,7 @@ import { styled, usePatchNodes } from '@toeverything/components/ui';
|
|||||||
import type { FC, PropsWithChildren } from 'react';
|
import type { FC, PropsWithChildren } from 'react';
|
||||||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||||||
import { RootContext } from './contexts';
|
import { RootContext } from './contexts';
|
||||||
import { SelectionRect, SelectionRef } from './selection';
|
import { SelectionRect, SelectionRef } from './Selection';
|
||||||
import {
|
import {
|
||||||
Protocol,
|
Protocol,
|
||||||
services,
|
services,
|
||||||
@@ -205,20 +205,17 @@ export const RenderRoot: FC<PropsWithChildren<RenderRootProps>> = ({
|
|||||||
{children}
|
{children}
|
||||||
{patchedNodes}
|
{patchedNodes}
|
||||||
</Content>
|
</Content>
|
||||||
{editor.isWhiteboard ? null : <ScrollBlank editor={editor} />}
|
|
||||||
{/** TODO: remove selectionManager insert */}
|
{/** TODO: remove selectionManager insert */}
|
||||||
{container && editor && (
|
{container && editor && (
|
||||||
<SelectionRect
|
<SelectionRect ref={selectionRef} editor={editor} />
|
||||||
ref={selectionRef}
|
|
||||||
container={container}
|
|
||||||
editor={editor}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
|
{editor.isWhiteboard ? null : <ScrollBlank editor={editor} />}
|
||||||
</Container>
|
</Container>
|
||||||
</RootContext.Provider>
|
</RootContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
function ScrollBlank({ editor }: { editor: BlockEditor }) {
|
function ScrollBlank({ editor }: { editor: BlockEditor }) {
|
||||||
const mouseMoved = useRef(false);
|
const mouseMoved = useRef(false);
|
||||||
|
|
||||||
@@ -281,6 +278,7 @@ const Container = styled('div')(
|
|||||||
overflowY: isWhiteboard ? 'unset' : 'auto',
|
overflowY: isWhiteboard ? 'unset' : 'auto',
|
||||||
padding: isWhiteboard ? 0 : '96px 150px 0 150px',
|
padding: isWhiteboard ? 0 : '96px 150px 0 150px',
|
||||||
minWidth: isWhiteboard ? 'unset' : '940px',
|
minWidth: isWhiteboard ? 'unset' : '940px',
|
||||||
|
position: 'relative',
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React, {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useCallback,
|
|
||||||
useImperativeHandle,
|
useImperativeHandle,
|
||||||
useEffect,
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
@@ -14,16 +13,13 @@ import { styled } from '@toeverything/components/ui';
|
|||||||
type MouseType = 'up' | 'down';
|
type MouseType = 'up' | 'down';
|
||||||
|
|
||||||
interface SelectionProps {
|
interface SelectionProps {
|
||||||
container?: HTMLElement;
|
|
||||||
editor: BlockEditor;
|
editor: BlockEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = style9.create({
|
const RectContainer = styled('div')({
|
||||||
selectionRect: {
|
backgroundColor: 'rgba(152, 172, 189, 0.1)',
|
||||||
backgroundColor: 'rgba(152, 172, 189, 0.1)',
|
position: 'absolute',
|
||||||
position: 'absolute',
|
zIndex: 99,
|
||||||
zIndex: 99,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
type VerticalTypes = 'up' | 'down' | null;
|
type VerticalTypes = 'up' | 'down' | null;
|
||||||
@@ -103,10 +99,10 @@ const setSelectedNodesByPoints = async (
|
|||||||
|
|
||||||
export const SelectionRect = forwardRef<SelectionRef, SelectionProps>(
|
export const SelectionRect = forwardRef<SelectionRef, SelectionProps>(
|
||||||
(props, ref) => {
|
(props, ref) => {
|
||||||
const { container, editor } = props;
|
const { editor } = props;
|
||||||
const { selectionManager, scrollManager } = editor;
|
const { selectionManager, scrollManager } = editor;
|
||||||
|
|
||||||
const [isShow, setIsShow] = useState<boolean>(false);
|
const [show, setShow] = useState<boolean>(false);
|
||||||
const startPointRef = useRef<Point>();
|
const startPointRef = useRef<Point>();
|
||||||
const endPointRef = useRef<Point>();
|
const endPointRef = useRef<Point>();
|
||||||
const [rect, setRect] = useState<Rect>(Rect.fromLTRB(0, 0, 0, 0));
|
const [rect, setRect] = useState<Rect>(Rect.fromLTRB(0, 0, 0, 0));
|
||||||
@@ -137,7 +133,7 @@ export const SelectionRect = forwardRef<SelectionRef, SelectionProps>(
|
|||||||
if (mouseType.current === 'down' && !startPointAtBlock.current) {
|
if (mouseType.current === 'down' && !startPointAtBlock.current) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
endPointRef.current = new Point(event.clientX, event.clientY);
|
endPointRef.current = new Point(event.clientX, event.clientY);
|
||||||
setIsShow(true);
|
setShow(true);
|
||||||
|
|
||||||
if (startPointRef.current) {
|
if (startPointRef.current) {
|
||||||
await setSelectedNodesByPoints(
|
await setSelectedNodesByPoints(
|
||||||
@@ -182,7 +178,7 @@ export const SelectionRect = forwardRef<SelectionRef, SelectionProps>(
|
|||||||
const onMouseUp = () => {
|
const onMouseUp = () => {
|
||||||
mouseType.current = 'up';
|
mouseType.current = 'up';
|
||||||
startPointAtBlock.current = false;
|
startPointAtBlock.current = false;
|
||||||
setIsShow(false);
|
setShow(false);
|
||||||
scrollManager.stopAutoScroll();
|
scrollManager.stopAutoScroll();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,11 +246,10 @@ export const SelectionRect = forwardRef<SelectionRef, SelectionProps>(
|
|||||||
scrollManager.onScrolling(scrollingCallback);
|
scrollManager.onScrolling(scrollingCallback);
|
||||||
|
|
||||||
return () => scrollManager.removeScrolling(scrollingCallback);
|
return () => scrollManager.removeScrolling(scrollingCallback);
|
||||||
}, [scrollManager]);
|
}, [editor, scrollManager]);
|
||||||
|
|
||||||
return isShow ? (
|
return show ? (
|
||||||
<div
|
<RectContainer
|
||||||
className={styles('selectionRect')}
|
|
||||||
style={{
|
style={{
|
||||||
left: `${rect.left}px`,
|
left: `${rect.left}px`,
|
||||||
top: `${rect.top}px`,
|
top: `${rect.top}px`,
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable max-lines */
|
/* eslint-disable max-lines */
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import HotKeys from 'hotkeys-js';
|
import HotKeys from 'hotkeys-js';
|
||||||
import LRUCache from 'lru-cache';
|
import LRUCache from 'lru-cache';
|
||||||
|
|
||||||
@@ -9,7 +8,7 @@ import type {
|
|||||||
ReturnEditorBlock,
|
ReturnEditorBlock,
|
||||||
UpdateEditorBlock,
|
UpdateEditorBlock,
|
||||||
} from '@toeverything/datasource/db-service';
|
} from '@toeverything/datasource/db-service';
|
||||||
import type { PatchNode, UnPatchNode } from '@toeverything/components/ui';
|
import type { PatchNode } from '@toeverything/components/ui';
|
||||||
|
|
||||||
import { AsyncBlock } from './block';
|
import { AsyncBlock } from './block';
|
||||||
import type { WorkspaceAndBlockId } from './block';
|
import type { WorkspaceAndBlockId } from './block';
|
||||||
@@ -46,7 +45,7 @@ export interface EditorCtorProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Editor implements Virgo {
|
export class Editor implements Virgo {
|
||||||
private cache_manager = new LRUCache<string, Promise<AsyncBlock | null>>({
|
private _cacheManager = new LRUCache<string, Promise<AsyncBlock | null>>({
|
||||||
max: 8192,
|
max: 8192,
|
||||||
ttl: 1000 * 60 * 30,
|
ttl: 1000 * 60 * 30,
|
||||||
});
|
});
|
||||||
@@ -136,7 +135,7 @@ export class Editor implements Virgo {
|
|||||||
|
|
||||||
public set container(v: HTMLDivElement) {
|
public set container(v: HTMLDivElement) {
|
||||||
this.ui_container = v;
|
this.ui_container = v;
|
||||||
this.init_clipboard();
|
this._initClipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get container() {
|
public get container() {
|
||||||
@@ -171,7 +170,7 @@ export class Editor implements Virgo {
|
|||||||
this.clipboard_populator?.disposeInternal();
|
this.clipboard_populator?.disposeInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
private init_clipboard() {
|
private _initClipboard() {
|
||||||
this._disposeClipboard();
|
this._disposeClipboard();
|
||||||
if (this.ui_container && !this._isDisposed) {
|
if (this.ui_container && !this._isDisposed) {
|
||||||
this.clipboard = new BrowserClipboard(
|
this.clipboard = new BrowserClipboard(
|
||||||
@@ -261,7 +260,7 @@ export class Editor implements Virgo {
|
|||||||
workspace,
|
workspace,
|
||||||
id,
|
id,
|
||||||
}: WorkspaceAndBlockId): Promise<AsyncBlock | null> {
|
}: WorkspaceAndBlockId): Promise<AsyncBlock | null> {
|
||||||
const block = this.cache_manager.get(id);
|
const block = this._cacheManager.get(id);
|
||||||
if (block) {
|
if (block) {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@@ -288,7 +287,7 @@ export class Editor implements Virgo {
|
|||||||
};
|
};
|
||||||
create();
|
create();
|
||||||
});
|
});
|
||||||
this.cache_manager.set(id, block_promise);
|
this._cacheManager.set(id, block_promise);
|
||||||
return await block_promise;
|
return await block_promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +300,7 @@ export class Editor implements Virgo {
|
|||||||
});
|
});
|
||||||
const block = await this._initBlock(blockData);
|
const block = await this._initBlock(blockData);
|
||||||
if (block) {
|
if (block) {
|
||||||
this.cache_manager.set(block.id, Promise.resolve(block));
|
this._cacheManager.set(block.id, Promise.resolve(block));
|
||||||
}
|
}
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,5 +172,6 @@ export class LeftMenuPlugin extends BasePlugin {
|
|||||||
public override dispose(): void {
|
public override dispose(): void {
|
||||||
// TODO: rxjs
|
// TODO: rxjs
|
||||||
this.root?.unmount();
|
this.root?.unmount();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
libs/components/layout/src/workspace-sidebar/page-tree/PageTree.tsx
Executable file
19
libs/components/layout/src/workspace-sidebar/page-tree/PageTree.tsx
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
import { styled } from '@toeverything/components/ui';
|
||||||
|
import { DndTree } from './DndTree';
|
||||||
|
import { useDndTreeAutoUpdate } from './use-page-tree';
|
||||||
|
|
||||||
|
const Root = styled('div')({
|
||||||
|
minWidth: 160,
|
||||||
|
maxWidth: 260,
|
||||||
|
marginLeft: 18,
|
||||||
|
marginRight: 6,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const PageTree = () => {
|
||||||
|
useDndTreeAutoUpdate();
|
||||||
|
return (
|
||||||
|
<Root>
|
||||||
|
<DndTree collapsible removable />
|
||||||
|
</Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export { PageTree } from './page-tree';
|
export { PageTree } from './PageTree';
|
||||||
export { usePageTree } from './use-page-tree';
|
export { usePageTree } from './use-page-tree';
|
||||||
|
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import style9 from 'style9';
|
|
||||||
|
|
||||||
import { DndTree } from './DndTree';
|
|
||||||
import { useDndTreeAutoUpdate } from './use-page-tree';
|
|
||||||
|
|
||||||
const styles = style9.create({
|
|
||||||
root: {
|
|
||||||
minWidth: 160,
|
|
||||||
maxWidth: 260,
|
|
||||||
marginLeft: 18,
|
|
||||||
marginRight: 6,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const PageTree = () => {
|
|
||||||
useDndTreeAutoUpdate();
|
|
||||||
return (
|
|
||||||
<div className={styles('root')}>
|
|
||||||
<DndTree collapsible removable />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user