mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 04:48:53 +00:00
Merge branch 'master' into bugfix/iframe
This commit is contained in:
@@ -9,6 +9,7 @@ type BlockContentWrapperProps = {
|
||||
children: ReactElement | null;
|
||||
};
|
||||
|
||||
// TODO: remove
|
||||
export const WrapperWithPendantAndDragDrop: FC<BlockContentWrapperProps> =
|
||||
function ({ block, children, editor }) {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { styled } from '@toeverything/components/ui';
|
||||
import type { AsyncBlock } from '../editor';
|
||||
import { PendantPopover } from './pendant-popover';
|
||||
@@ -11,74 +10,68 @@ interface BlockTagProps {
|
||||
block: AsyncBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Need to be refactored
|
||||
*/
|
||||
export const BlockPendantProvider: FC<PropsWithChildren<BlockTagProps>> = ({
|
||||
block,
|
||||
children,
|
||||
}) => {
|
||||
const [container, setContainer] = useState<HTMLElement>(null);
|
||||
const [isHover, setIsHover] = useState(false);
|
||||
return (
|
||||
<Container ref={(dom: HTMLElement) => setContainer(dom)}>
|
||||
<Container>
|
||||
{children}
|
||||
{container && (
|
||||
<PendantPopover
|
||||
block={block}
|
||||
container={container}
|
||||
onVisibleChange={visible => {
|
||||
setIsHover(visible);
|
||||
}}
|
||||
>
|
||||
<StyledTriggerLine
|
||||
className="triggerLine"
|
||||
isHover={isHover}
|
||||
/>
|
||||
</PendantPopover>
|
||||
)}
|
||||
|
||||
<PendantPopover block={block}>
|
||||
<StyledTriggerLine />
|
||||
</PendantPopover>
|
||||
|
||||
<PendantRender block={block} />
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
const Container = styled('div')({
|
||||
export const LINE_GAP = 16;
|
||||
const TAG_GAP = 4;
|
||||
|
||||
const StyledTriggerLine = styled('div')({
|
||||
padding: `${TAG_GAP}px 0`,
|
||||
width: '100px',
|
||||
cursor: 'default',
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
position: 'relative',
|
||||
padding: '4px',
|
||||
'&:hover .triggerLine::before': {
|
||||
display: 'flex',
|
||||
|
||||
'::before': {
|
||||
content: "''",
|
||||
width: '100%',
|
||||
height: '2px',
|
||||
background: '#dadada',
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
left: '0',
|
||||
top: '4px',
|
||||
},
|
||||
'::after': {
|
||||
content: "''",
|
||||
width: '0',
|
||||
height: '2px',
|
||||
background: '#aac4d5',
|
||||
display: 'block',
|
||||
position: 'absolute',
|
||||
left: '0',
|
||||
top: '4px',
|
||||
transition: 'width .3s',
|
||||
},
|
||||
});
|
||||
|
||||
const StyledTriggerLine = styled('div')<{ isHover: boolean }>(({ isHover }) => {
|
||||
return {
|
||||
padding: '4px 0',
|
||||
width: '100px',
|
||||
cursor: 'default',
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
position: 'relative',
|
||||
|
||||
'::before': {
|
||||
content: "''",
|
||||
width: '100%',
|
||||
height: '2px',
|
||||
background: '#dadada',
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
left: '0',
|
||||
top: '4px',
|
||||
const Container = styled('div')({
|
||||
position: 'relative',
|
||||
paddingBottom: `${LINE_GAP - TAG_GAP * 2}px`,
|
||||
'&:hover': {
|
||||
[StyledTriggerLine.toString()]: {
|
||||
'&::before': {
|
||||
display: 'flex',
|
||||
},
|
||||
'&::after': {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
'::after': {
|
||||
content: "''",
|
||||
width: isHover ? '100%' : '0',
|
||||
height: '2px',
|
||||
background: '#aac4d5',
|
||||
display: 'block',
|
||||
position: 'absolute',
|
||||
left: '0',
|
||||
top: '4px',
|
||||
transition: 'width .3s',
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { FC, useRef } from 'react';
|
||||
import { FC, useRef } from 'react';
|
||||
import { AsyncBlock } from '../../editor';
|
||||
import { PendantHistoryPanel } from '../pendant-history-panel';
|
||||
import {
|
||||
@@ -21,8 +21,6 @@ export const PendantPopover: FC<
|
||||
pointerEnterDelay={300}
|
||||
pointerLeaveDelay={200}
|
||||
placement="bottom-start"
|
||||
// visible={true}
|
||||
// trigger="click"
|
||||
content={
|
||||
<PendantHistoryPanel
|
||||
block={block}
|
||||
|
||||
@@ -12,6 +12,7 @@ enum DragType {
|
||||
}
|
||||
|
||||
const DRAG_STATE_CHANGE_EVENT_KEY = 'dragStateChange';
|
||||
const MAX_GRID_BLOCK_FLOOR = 3;
|
||||
export class DragDropManager {
|
||||
private _editor: Editor;
|
||||
private _enabled: boolean;
|
||||
@@ -231,6 +232,17 @@ export class DragDropManager {
|
||||
if (!(await this._canBeDrop(event))) {
|
||||
direction = BlockDropPlacement.none;
|
||||
}
|
||||
if (
|
||||
direction === BlockDropPlacement.left ||
|
||||
direction === BlockDropPlacement.right
|
||||
) {
|
||||
const path = await this._editor.getBlockPath(blockId);
|
||||
const gridBlocks = path.filter(block => block.type === 'grid');
|
||||
// limit grid block floor counts
|
||||
if (gridBlocks.length >= MAX_GRID_BLOCK_FLOOR) {
|
||||
direction = BlockDropPlacement.none;
|
||||
}
|
||||
}
|
||||
this._setBlockDragDirection(direction);
|
||||
return direction;
|
||||
}
|
||||
|
||||
@@ -340,7 +340,20 @@ export class Editor implements Virgo {
|
||||
const rootBlockId = this.getRootBlockId();
|
||||
const rootBlock = await this.getBlockById(rootBlockId);
|
||||
const blockList: Array<AsyncBlock> = rootBlock ? [rootBlock] : [];
|
||||
const children = (await rootBlock?.children()) || [];
|
||||
return [...blockList, ...(await this.getOffspring(rootBlockId))];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* get all offspring of block
|
||||
* @param {string} id
|
||||
* @return {*}
|
||||
* @memberof Editor
|
||||
*/
|
||||
async getOffspring(id: string) {
|
||||
const block = await this.getBlockById(id);
|
||||
const blockList: Array<AsyncBlock> = [];
|
||||
const children = (await block?.children()) || [];
|
||||
for (const block of children) {
|
||||
if (!block) {
|
||||
continue;
|
||||
@@ -379,6 +392,20 @@ export class Editor implements Virgo {
|
||||
return lastBlock;
|
||||
}
|
||||
|
||||
async getBlockPath(id: string) {
|
||||
const block = await this.getBlockById(id);
|
||||
if (!block) {
|
||||
return [];
|
||||
}
|
||||
const path = [block];
|
||||
let parent = await block.parent();
|
||||
while (parent) {
|
||||
path.unshift(parent);
|
||||
parent = await parent.parent();
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
async getBlockByPoint(point: Point) {
|
||||
const blockList = await this.getBlockList();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user