mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 10:42:00 +03:00
Merge pull request #318 from toeverything/feat/block-render
Feat/block render
This commit is contained in:
commit
15055bc7c6
@ -1,7 +1,6 @@
|
|||||||
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
|
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
RenderBlock,
|
|
||||||
RenderRoot,
|
RenderRoot,
|
||||||
type BlockEditor,
|
type BlockEditor,
|
||||||
} from '@toeverything/components/editor-core';
|
} from '@toeverything/components/editor-core';
|
||||||
@ -88,9 +87,7 @@ export const AffineEditor = forwardRef<BlockEditor, AffineEditorProps>(
|
|||||||
editor={editor}
|
editor={editor}
|
||||||
editorElement={AffineEditor as any}
|
editorElement={AffineEditor as any}
|
||||||
scrollBlank={scrollBlank}
|
scrollBlank={scrollBlank}
|
||||||
>
|
/>
|
||||||
<RenderBlock blockId={editor.getRootBlockId()} />
|
|
||||||
</RenderRoot>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,29 +1,28 @@
|
|||||||
import type { TextProps } from '@toeverything/components/common';
|
import type { TextProps } from '@toeverything/components/common';
|
||||||
import {
|
import {
|
||||||
ContentColumnValue,
|
ContentColumnValue,
|
||||||
services,
|
|
||||||
Protocol,
|
Protocol,
|
||||||
|
services,
|
||||||
} from '@toeverything/datasource/db-service';
|
} from '@toeverything/datasource/db-service';
|
||||||
import { type CreateView } from '@toeverything/framework/virgo';
|
import { type CreateView } from '@toeverything/framework/virgo';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
BlockPendantProvider,
|
||||||
|
RenderBlockChildren,
|
||||||
|
supportChildren,
|
||||||
|
useOnSelect,
|
||||||
|
} from '@toeverything/components/editor-core';
|
||||||
|
import { styled } from '@toeverything/components/ui';
|
||||||
|
import { BlockContainer } from '../../components/BlockContainer';
|
||||||
|
import { List } from '../../components/style-container';
|
||||||
import {
|
import {
|
||||||
TextManage,
|
TextManage,
|
||||||
type ExtendedTextUtils,
|
type ExtendedTextUtils,
|
||||||
} from '../../components/text-manage';
|
} from '../../components/text-manage';
|
||||||
import { tabBlock } from '../../utils/indent';
|
import { tabBlock } from '../../utils/indent';
|
||||||
|
import { BulletIcon, getChildrenType, NumberType } from './data';
|
||||||
import { BulletBlock, BulletProperties } from './types';
|
import { BulletBlock, BulletProperties } from './types';
|
||||||
import {
|
|
||||||
supportChildren,
|
|
||||||
RenderBlockChildren,
|
|
||||||
useOnSelect,
|
|
||||||
BlockPendantProvider,
|
|
||||||
} from '@toeverything/components/editor-core';
|
|
||||||
import { List } from '../../components/style-container';
|
|
||||||
import { getChildrenType, BulletIcon, NumberType } from './data';
|
|
||||||
import { IndentWrapper } from '../../components/IndentWrapper';
|
|
||||||
import { BlockContainer } from '../../components/BlockContainer';
|
|
||||||
import { styled } from '@toeverything/components/ui';
|
|
||||||
|
|
||||||
export const defaultBulletProps: BulletProperties = {
|
export const defaultBulletProps: BulletProperties = {
|
||||||
text: { value: [{ text: '' }] },
|
text: { value: [{ text: '' }] },
|
||||||
@ -208,9 +207,7 @@ export const BulletView = ({ block, editor }: CreateView) => {
|
|||||||
</div>
|
</div>
|
||||||
</List>
|
</List>
|
||||||
</BlockPendantProvider>
|
</BlockPendantProvider>
|
||||||
<IndentWrapper>
|
|
||||||
<RenderBlockChildren block={block} />
|
<RenderBlockChildren block={block} />
|
||||||
</IndentWrapper>
|
|
||||||
</BlockContainer>
|
</BlockContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
|
import {
|
||||||
|
DefaultColumnsValue,
|
||||||
|
Protocol,
|
||||||
|
} from '@toeverything/datasource/db-service';
|
||||||
import {
|
import {
|
||||||
AsyncBlock,
|
AsyncBlock,
|
||||||
BaseView,
|
BaseView,
|
||||||
CreateView,
|
getTextHtml,
|
||||||
getTextProperties,
|
getTextProperties,
|
||||||
SelectBlock,
|
SelectBlock,
|
||||||
getTextHtml,
|
|
||||||
} from '@toeverything/framework/virgo';
|
} from '@toeverything/framework/virgo';
|
||||||
import {
|
|
||||||
Protocol,
|
|
||||||
DefaultColumnsValue,
|
|
||||||
} from '@toeverything/datasource/db-service';
|
|
||||||
// import { withTreeViewChildren } from '../../utils/with-tree-view-children';
|
// import { withTreeViewChildren } from '../../utils/with-tree-view-children';
|
||||||
import { defaultBulletProps, BulletView } from './BulletView';
|
import { BulletView, defaultBulletProps } from './BulletView';
|
||||||
import { IndentWrapper } from '../../components/IndentWrapper';
|
|
||||||
|
|
||||||
export class BulletBlock extends BaseView {
|
export class BulletBlock extends BaseView {
|
||||||
public type = Protocol.Block.Type.bullet;
|
public type = Protocol.Block.Type.bullet;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { RenderBlock } from '@toeverything/components/editor-core';
|
import { useBlockRender } from '@toeverything/components/editor-core';
|
||||||
import { ChildrenView, CreateView } from '@toeverything/framework/virgo';
|
import { ChildrenView, CreateView } from '@toeverything/framework/virgo';
|
||||||
|
|
||||||
export const GridItemRender = function (
|
export const GridItemRender = function (
|
||||||
@ -6,10 +6,11 @@ export const GridItemRender = function (
|
|||||||
) {
|
) {
|
||||||
const GridItem = function (props: CreateView) {
|
const GridItem = function (props: CreateView) {
|
||||||
const { block } = props;
|
const { block } = props;
|
||||||
|
const { BlockRender } = useBlockRender();
|
||||||
const children = (
|
const children = (
|
||||||
<>
|
<>
|
||||||
{block.childrenIds.map(id => {
|
{block.childrenIds.map(id => {
|
||||||
return <RenderBlock key={id} blockId={id} />;
|
return <BlockRender key={id} blockId={id} />;
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { RenderBlock } from '@toeverything/components/editor-core';
|
import { useBlockRender } from '@toeverything/components/editor-core';
|
||||||
import { CreateView } from '@toeverything/framework/virgo';
|
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { GridHandle } from './GirdHandle';
|
|
||||||
import { styled } from '@toeverything/components/ui';
|
import { styled } from '@toeverything/components/ui';
|
||||||
|
import { Protocol } from '@toeverything/datasource/db-service';
|
||||||
|
import { CreateView } from '@toeverything/framework/virgo';
|
||||||
|
import { debounce, domToRect, Point } from '@toeverything/utils';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import {
|
import {
|
||||||
GRID_ITEM_CLASS_NAME,
|
GRID_ITEM_CLASS_NAME,
|
||||||
GRID_ITEM_CONTENT_CLASS_NAME,
|
GRID_ITEM_CONTENT_CLASS_NAME,
|
||||||
} from '../grid-item/GridItem';
|
} from '../grid-item/GridItem';
|
||||||
import { debounce, domToRect, Point } from '@toeverything/utils';
|
import { GridHandle } from './GirdHandle';
|
||||||
import clsx from 'clsx';
|
|
||||||
import { Protocol } from '@toeverything/datasource/db-service';
|
|
||||||
|
|
||||||
const DB_UPDATE_DELAY = 50;
|
const DB_UPDATE_DELAY = 50;
|
||||||
const GRID_ON_DRAG_CLASS = 'grid-layout-on-drag';
|
const GRID_ON_DRAG_CLASS = 'grid-layout-on-drag';
|
||||||
@ -31,6 +31,7 @@ export const Grid = function (props: CreateView) {
|
|||||||
const originalLeftWidth = useRef<number>(gridItemMinWidth);
|
const originalLeftWidth = useRef<number>(gridItemMinWidth);
|
||||||
const originalRightWidth = useRef<number>(gridItemMinWidth);
|
const originalRightWidth = useRef<number>(gridItemMinWidth);
|
||||||
const [alertHandleId, setAlertHandleId] = useState<string>(null);
|
const [alertHandleId, setAlertHandleId] = useState<string>(null);
|
||||||
|
const { BlockRender } = useBlockRender();
|
||||||
|
|
||||||
const getLeftRightGridItemDomByIndex = (index: number) => {
|
const getLeftRightGridItemDomByIndex = (index: number) => {
|
||||||
const gridItems = Array.from(gridContainerRef.current?.children).filter(
|
const gridItems = Array.from(gridContainerRef.current?.children).filter(
|
||||||
@ -226,7 +227,7 @@ export const Grid = function (props: CreateView) {
|
|||||||
key={id}
|
key={id}
|
||||||
className={GRID_ITEM_CLASS_NAME}
|
className={GRID_ITEM_CLASS_NAME}
|
||||||
>
|
>
|
||||||
<RenderBlock hasContainer={false} blockId={id} />
|
<BlockRender hasContainer={false} blockId={id} />
|
||||||
<GridHandle
|
<GridHandle
|
||||||
onDrag={event => handleDragGrid(event, i)}
|
onDrag={event => handleDragGrid(event, i)}
|
||||||
editor={editor}
|
editor={editor}
|
||||||
|
@ -2,5 +2,5 @@ import { RenderBlockChildren } from '@toeverything/components/editor-core';
|
|||||||
import type { CreateView } from '@toeverything/framework/virgo';
|
import type { CreateView } from '@toeverything/framework/virgo';
|
||||||
|
|
||||||
export const ScenePage = ({ block }: CreateView) => {
|
export const ScenePage = ({ block }: CreateView) => {
|
||||||
return <RenderBlockChildren block={block} />;
|
return <RenderBlockChildren block={block} indent={false} />;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
KanbanCard,
|
KanbanCard,
|
||||||
RenderBlock,
|
useBlockRender,
|
||||||
useEditor,
|
useEditor,
|
||||||
useKanban,
|
useKanban,
|
||||||
} from '@toeverything/components/editor-core';
|
} from '@toeverything/components/editor-core';
|
||||||
@ -94,6 +94,7 @@ export const CardItem = ({
|
|||||||
const [editable, setEditable] = useState(false);
|
const [editable, setEditable] = useState(false);
|
||||||
const showKanbanRefPageFlag = useFlag('ShowKanbanRefPage', false);
|
const showKanbanRefPageFlag = useFlag('ShowKanbanRefPage', false);
|
||||||
const { editor } = useEditor();
|
const { editor } = useEditor();
|
||||||
|
const { BlockRender } = useBlockRender();
|
||||||
|
|
||||||
const onAddItem = async () => {
|
const onAddItem = async () => {
|
||||||
setEditable(true);
|
setEditable(true);
|
||||||
@ -114,7 +115,7 @@ export const CardItem = ({
|
|||||||
<MuiClickAwayListener onClickAway={() => setEditable(false)}>
|
<MuiClickAwayListener onClickAway={() => setEditable(false)}>
|
||||||
<CardContainer>
|
<CardContainer>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<RenderBlock blockId={id} />
|
<BlockRender blockId={id} />
|
||||||
</CardContent>
|
</CardContent>
|
||||||
{showKanbanRefPageFlag && !editable && (
|
{showKanbanRefPageFlag && !editable && (
|
||||||
<Overlay onClick={onClickCard}>
|
<Overlay onClick={onClickCard}>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { TextProps } from '@toeverything/components/common';
|
import { TextProps } from '@toeverything/components/common';
|
||||||
import {
|
import {
|
||||||
ContentColumnValue,
|
ContentColumnValue,
|
||||||
services,
|
|
||||||
Protocol,
|
Protocol,
|
||||||
|
services,
|
||||||
} from '@toeverything/datasource/db-service';
|
} from '@toeverything/datasource/db-service';
|
||||||
import { type CreateView } from '@toeverything/framework/virgo';
|
import { type CreateView } from '@toeverything/framework/virgo';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
@ -11,18 +11,17 @@ import {
|
|||||||
type ExtendedTextUtils,
|
type ExtendedTextUtils,
|
||||||
} from '../../components/text-manage';
|
} from '../../components/text-manage';
|
||||||
import { tabBlock } from '../../utils/indent';
|
import { tabBlock } from '../../utils/indent';
|
||||||
import { IndentWrapper } from '../../components/IndentWrapper';
|
|
||||||
import type { Numbered, NumberedAsyncBlock } from './types';
|
import type { Numbered, NumberedAsyncBlock } from './types';
|
||||||
|
|
||||||
import { getChildrenType, getNumber } from './data';
|
|
||||||
import {
|
import {
|
||||||
supportChildren,
|
|
||||||
RenderBlockChildren,
|
|
||||||
useOnSelect,
|
|
||||||
BlockPendantProvider,
|
BlockPendantProvider,
|
||||||
|
RenderBlockChildren,
|
||||||
|
supportChildren,
|
||||||
|
useOnSelect,
|
||||||
} from '@toeverything/components/editor-core';
|
} from '@toeverything/components/editor-core';
|
||||||
import { List } from '../../components/style-container';
|
|
||||||
import { BlockContainer } from '../../components/BlockContainer';
|
import { BlockContainer } from '../../components/BlockContainer';
|
||||||
|
import { List } from '../../components/style-container';
|
||||||
|
import { getChildrenType, getNumber } from './data';
|
||||||
|
|
||||||
export const defaultTodoProps: Numbered = {
|
export const defaultTodoProps: Numbered = {
|
||||||
text: { value: [{ text: '' }] },
|
text: { value: [{ text: '' }] },
|
||||||
@ -204,9 +203,7 @@ export const NumberedView = ({ block, editor }: CreateView) => {
|
|||||||
</List>
|
</List>
|
||||||
</BlockPendantProvider>
|
</BlockPendantProvider>
|
||||||
|
|
||||||
<IndentWrapper>
|
|
||||||
<RenderBlockChildren block={block} />
|
<RenderBlockChildren block={block} />
|
||||||
</IndentWrapper>
|
|
||||||
</BlockContainer>
|
</BlockContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
|
import {
|
||||||
|
DefaultColumnsValue,
|
||||||
|
Protocol,
|
||||||
|
} from '@toeverything/datasource/db-service';
|
||||||
import {
|
import {
|
||||||
AsyncBlock,
|
AsyncBlock,
|
||||||
BaseView,
|
BaseView,
|
||||||
|
getTextHtml,
|
||||||
getTextProperties,
|
getTextProperties,
|
||||||
SelectBlock,
|
SelectBlock,
|
||||||
getTextHtml,
|
|
||||||
} from '@toeverything/framework/virgo';
|
} from '@toeverything/framework/virgo';
|
||||||
import {
|
|
||||||
Protocol,
|
|
||||||
DefaultColumnsValue,
|
|
||||||
} from '@toeverything/datasource/db-service';
|
|
||||||
// import { withTreeViewChildren } from '../../utils/with-tree-view-children';
|
// import { withTreeViewChildren } from '../../utils/with-tree-view-children';
|
||||||
import { defaultTodoProps, NumberedView } from './NumberedView';
|
import { defaultTodoProps, NumberedView } from './NumberedView';
|
||||||
import { IndentWrapper } from '../../components/IndentWrapper';
|
|
||||||
|
|
||||||
export class NumberedBlock extends BaseView {
|
export class NumberedBlock extends BaseView {
|
||||||
public type = Protocol.Block.Type.numbered;
|
public type = Protocol.Block.Type.numbered;
|
||||||
|
@ -12,7 +12,6 @@ import { styled } from '@toeverything/components/ui';
|
|||||||
import { Protocol } from '@toeverything/datasource/db-service';
|
import { Protocol } from '@toeverything/datasource/db-service';
|
||||||
import { CreateView } from '@toeverything/framework/virgo';
|
import { CreateView } from '@toeverything/framework/virgo';
|
||||||
import { BlockContainer } from '../../components/BlockContainer';
|
import { BlockContainer } from '../../components/BlockContainer';
|
||||||
import { IndentWrapper } from '../../components/IndentWrapper';
|
|
||||||
import { TextManage } from '../../components/text-manage';
|
import { TextManage } from '../../components/text-manage';
|
||||||
import { dedentBlock, tabBlock } from '../../utils/indent';
|
import { dedentBlock, tabBlock } from '../../utils/indent';
|
||||||
interface CreateTextView extends CreateView {
|
interface CreateTextView extends CreateView {
|
||||||
@ -255,9 +254,7 @@ export const TextView = ({
|
|||||||
handleTab={onTab}
|
handleTab={onTab}
|
||||||
/>
|
/>
|
||||||
</BlockPendantProvider>
|
</BlockPendantProvider>
|
||||||
<IndentWrapper>
|
|
||||||
<RenderBlockChildren block={block} />
|
<RenderBlockChildren block={block} />
|
||||||
</IndentWrapper>
|
|
||||||
</BlockContainer>
|
</BlockContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import { TextProps } from '@toeverything/components/common';
|
import { TextProps } from '@toeverything/components/common';
|
||||||
|
import {
|
||||||
|
AsyncBlock,
|
||||||
|
BlockPendantProvider,
|
||||||
|
CreateView,
|
||||||
|
useOnSelect,
|
||||||
|
} from '@toeverything/components/editor-core';
|
||||||
import { styled } from '@toeverything/components/ui';
|
import { styled } from '@toeverything/components/ui';
|
||||||
import {
|
import {
|
||||||
ContentColumnValue,
|
ContentColumnValue,
|
||||||
Protocol,
|
Protocol,
|
||||||
} from '@toeverything/datasource/db-service';
|
} from '@toeverything/datasource/db-service';
|
||||||
import { AsyncBlock, type CreateView } from '@toeverything/framework/virgo';
|
import { useRef, useState } from 'react';
|
||||||
import { useRef } from 'react';
|
import { BlockContainer } from '../../components/BlockContainer';
|
||||||
import {
|
import {
|
||||||
TextManage,
|
TextManage,
|
||||||
type ExtendedTextUtils,
|
type ExtendedTextUtils,
|
||||||
@ -36,6 +42,10 @@ const todoIsEmpty = (contentValue: ContentColumnValue): boolean => {
|
|||||||
export const TodoView = ({ block, editor }: CreateView) => {
|
export const TodoView = ({ block, editor }: CreateView) => {
|
||||||
const properties = { ...defaultTodoProps, ...block.getProperties() };
|
const properties = { ...defaultTodoProps, ...block.getProperties() };
|
||||||
const text_ref = useRef<ExtendedTextUtils>(null);
|
const text_ref = useRef<ExtendedTextUtils>(null);
|
||||||
|
const [isSelect, setIsSelect] = useState<boolean>(false);
|
||||||
|
useOnSelect(block.id, (isSelect: boolean) => {
|
||||||
|
setIsSelect(isSelect);
|
||||||
|
});
|
||||||
|
|
||||||
const turn_into_text_block = async () => {
|
const turn_into_text_block = async () => {
|
||||||
// Convert to text block
|
// Convert to text block
|
||||||
@ -121,6 +131,8 @@ export const TodoView = ({ block, editor }: CreateView) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<BlockContainer editor={editor} block={block} selected={isSelect}>
|
||||||
|
<BlockPendantProvider block={block}>
|
||||||
<TodoBlock>
|
<TodoBlock>
|
||||||
<div className={'checkBoxContainer'}>
|
<div className={'checkBoxContainer'}>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
@ -131,7 +143,9 @@ export const TodoView = ({ block, editor }: CreateView) => {
|
|||||||
|
|
||||||
<div className={'textContainer'}>
|
<div className={'textContainer'}>
|
||||||
<TextManage
|
<TextManage
|
||||||
className={properties.checked?.value ? 'checked' : ''}
|
className={
|
||||||
|
properties.checked?.value ? 'checked' : ''
|
||||||
|
}
|
||||||
ref={text_ref}
|
ref={text_ref}
|
||||||
editor={editor}
|
editor={editor}
|
||||||
block={block}
|
block={block}
|
||||||
@ -143,6 +157,8 @@ export const TodoView = ({ block, editor }: CreateView) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</TodoBlock>
|
</TodoBlock>
|
||||||
|
</BlockPendantProvider>
|
||||||
|
</BlockContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
import {
|
import {
|
||||||
BaseView,
|
|
||||||
getTextProperties,
|
|
||||||
AsyncBlock,
|
AsyncBlock,
|
||||||
SelectBlock,
|
BaseView,
|
||||||
getTextHtml,
|
getTextHtml,
|
||||||
} from '@toeverything/framework/virgo';
|
getTextProperties,
|
||||||
// import type { CreateView } from '@toeverything/framework/virgo';
|
SelectBlock,
|
||||||
|
withTreeViewChildren,
|
||||||
|
} from '@toeverything/components/editor-core';
|
||||||
import {
|
import {
|
||||||
Protocol,
|
|
||||||
DefaultColumnsValue,
|
DefaultColumnsValue,
|
||||||
|
Protocol,
|
||||||
} from '@toeverything/datasource/db-service';
|
} from '@toeverything/datasource/db-service';
|
||||||
// import { withTreeViewChildren } from '../../utils/with-tree-view-children';
|
import { defaultTodoProps, TodoView } from './TodoView';
|
||||||
import { withTreeViewChildren } from '../../utils/WithTreeViewChildren';
|
|
||||||
import { TodoView, defaultTodoProps } from './TodoView';
|
|
||||||
import type { TodoAsyncBlock } from './types';
|
import type { TodoAsyncBlock } from './types';
|
||||||
|
|
||||||
export class TodoBlock extends BaseView {
|
export class TodoBlock extends BaseView {
|
||||||
|
@ -23,7 +23,7 @@ export const BlockContainer = function ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Container = styled('div')<{ selected: boolean }>(
|
export const Container = styled('div')<{ selected?: boolean }>(
|
||||||
({ selected, theme }) => ({
|
({ selected, theme }) => ({
|
||||||
backgroundColor: selected ? theme.affine.palette.textSelected : '',
|
backgroundColor: selected ? theme.affine.palette.textSelected : '',
|
||||||
marginBottom: '2px',
|
marginBottom: '2px',
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
import { PropsWithChildren } from 'react';
|
|
||||||
import { ChildrenView } from '@toeverything/framework/virgo';
|
|
||||||
import { styled } from '@toeverything/components/ui';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indent rendering child nodes
|
|
||||||
*/
|
|
||||||
export const IndentWrapper = (props: PropsWithChildren) => {
|
|
||||||
return <StyledIdentWrapper>{props.children}</StyledIdentWrapper>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const StyledIdentWrapper = styled('div')({
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
// TODO: marginLeft should use theme provided by styled
|
|
||||||
marginLeft: '30px',
|
|
||||||
});
|
|
@ -1 +0,0 @@
|
|||||||
export * from './IndentWrapper';
|
|
@ -1,4 +1,5 @@
|
|||||||
export const isYoutubeUrl = (url?: string): boolean => {
|
export const isYoutubeUrl = (url?: string): boolean => {
|
||||||
|
if (!url) return false;
|
||||||
const allowedHosts = ['www.youtu.be', 'www.youtube.com'];
|
const allowedHosts = ['www.youtu.be', 'www.youtube.com'];
|
||||||
const host = new URL(url).host;
|
const host = new URL(url).host;
|
||||||
return allowedHosts.includes(host);
|
return allowedHosts.includes(host);
|
||||||
|
@ -1,22 +1,34 @@
|
|||||||
import { createContext, useContext } from 'react';
|
|
||||||
import type { BlockEditor, AsyncBlock } from './editor';
|
|
||||||
import { genErrorObj } from '@toeverything/utils';
|
import { genErrorObj } from '@toeverything/utils';
|
||||||
|
import { createContext, PropsWithChildren, useContext } from 'react';
|
||||||
|
import type { AsyncBlock, BlockEditor } from './editor';
|
||||||
|
|
||||||
const RootContext = createContext<{
|
type EditorProps = {
|
||||||
editor: BlockEditor;
|
editor: BlockEditor;
|
||||||
// TODO: Temporary fix, dependencies in the new architecture are bottom-up, editors do not need to be passed down from the top
|
// TODO: Temporary fix, dependencies in the new architecture are bottom-up, editors do not need to be passed down from the top
|
||||||
editorElement: () => JSX.Element;
|
editorElement: () => JSX.Element;
|
||||||
}>(
|
};
|
||||||
|
|
||||||
|
const EditorContext = createContext<EditorProps>(
|
||||||
genErrorObj(
|
genErrorObj(
|
||||||
'Failed to get context! The context only can use under the "render-root"'
|
'Failed to get EditorContext! The context only can use under the "render-root"'
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
) as any
|
) as any
|
||||||
);
|
);
|
||||||
|
|
||||||
export const EditorProvider = RootContext.Provider;
|
|
||||||
|
|
||||||
export const useEditor = () => {
|
export const useEditor = () => {
|
||||||
return useContext(RootContext);
|
return useContext(EditorContext);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const EditorProvider = ({
|
||||||
|
editor,
|
||||||
|
editorElement,
|
||||||
|
children,
|
||||||
|
}: PropsWithChildren<EditorProps>) => {
|
||||||
|
return (
|
||||||
|
<EditorContext.Provider value={{ editor, editorElement }}>
|
||||||
|
{children}
|
||||||
|
</EditorContext.Provider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,12 +4,12 @@ import {
|
|||||||
services,
|
services,
|
||||||
type ReturnUnobserve,
|
type ReturnUnobserve,
|
||||||
} from '@toeverything/datasource/db-service';
|
} from '@toeverything/datasource/db-service';
|
||||||
import type { PropsWithChildren } from 'react';
|
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { EditorProvider } from './Contexts';
|
import { EditorProvider } from './Contexts';
|
||||||
import type { BlockEditor } from './editor';
|
import type { BlockEditor } from './editor';
|
||||||
import { useIsOnDrag } from './hooks';
|
import { useIsOnDrag } from './hooks';
|
||||||
import { addNewGroup, appendNewGroup } from './recast-block';
|
import { addNewGroup, appendNewGroup } from './recast-block';
|
||||||
|
import { BlockRenderProvider, RenderBlock } from './render-block';
|
||||||
import { SelectionRect, SelectionRef } from './Selection';
|
import { SelectionRect, SelectionRef } from './Selection';
|
||||||
|
|
||||||
interface RenderRootProps {
|
interface RenderRootProps {
|
||||||
@ -24,11 +24,7 @@ interface RenderRootProps {
|
|||||||
const MAX_PAGE_WIDTH = 5000;
|
const MAX_PAGE_WIDTH = 5000;
|
||||||
export const MIN_PAGE_WIDTH = 1480;
|
export const MIN_PAGE_WIDTH = 1480;
|
||||||
|
|
||||||
export const RenderRoot = ({
|
export const RenderRoot = ({ editor, editorElement }: RenderRootProps) => {
|
||||||
editor,
|
|
||||||
editorElement,
|
|
||||||
children,
|
|
||||||
}: PropsWithChildren<RenderRootProps>) => {
|
|
||||||
const selectionRef = useRef<SelectionRef>(null);
|
const selectionRef = useRef<SelectionRef>(null);
|
||||||
const triggeredBySelect = useRef(false);
|
const triggeredBySelect = useRef(false);
|
||||||
const [pageWidth, setPageWidth] = useState<number>(MIN_PAGE_WIDTH);
|
const [pageWidth, setPageWidth] = useState<number>(MIN_PAGE_WIDTH);
|
||||||
@ -158,7 +154,8 @@ export const RenderRoot = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EditorProvider value={{ editor, editorElement }}>
|
<EditorProvider editor={editor} editorElement={editorElement}>
|
||||||
|
<BlockRenderProvider blockRender={RenderBlock}>
|
||||||
<Container
|
<Container
|
||||||
isEdgeless={editor.isEdgeless}
|
isEdgeless={editor.isEdgeless}
|
||||||
ref={ref => {
|
ref={ref => {
|
||||||
@ -184,13 +181,16 @@ export const RenderRoot = ({
|
|||||||
isOnDrag={isOnDrag}
|
isOnDrag={isOnDrag}
|
||||||
>
|
>
|
||||||
<Content style={{ maxWidth: pageWidth + 'px' }}>
|
<Content style={{ maxWidth: pageWidth + 'px' }}>
|
||||||
{children}
|
<RenderBlock blockId={editor.getRootBlockId()} />
|
||||||
</Content>
|
</Content>
|
||||||
{/** TODO: remove selectionManager insert */}
|
{/** TODO: remove selectionManager insert */}
|
||||||
{editor && <SelectionRect ref={selectionRef} editor={editor} />}
|
{editor && (
|
||||||
|
<SelectionRect ref={selectionRef} editor={editor} />
|
||||||
|
)}
|
||||||
{editor.isEdgeless ? null : <ScrollBlank editor={editor} />}
|
{editor.isEdgeless ? null : <ScrollBlank editor={editor} />}
|
||||||
{patchedNodes}
|
{patchedNodes}
|
||||||
</Container>
|
</Container>
|
||||||
|
</BlockRenderProvider>
|
||||||
</EditorProvider>
|
</EditorProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -251,7 +251,7 @@ function ScrollBlank({ editor }: { editor: BlockEditor }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollBlankContainter
|
<ScrollBlankContainer
|
||||||
onMouseDown={onMouseDown}
|
onMouseDown={onMouseDown}
|
||||||
onMouseMove={onMouseMove}
|
onMouseMove={onMouseMove}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
@ -283,7 +283,7 @@ const Content = styled('div')({
|
|||||||
transitionTimingFunction: 'ease-in',
|
transitionTimingFunction: 'ease-in',
|
||||||
});
|
});
|
||||||
|
|
||||||
const ScrollBlankContainter = styled('div')({
|
const ScrollBlankContainer = styled('div')({
|
||||||
paddingBottom: '30vh',
|
paddingBottom: '30vh',
|
||||||
margin: `0 -${PADDING_X}px`,
|
margin: `0 -${PADDING_X}px`,
|
||||||
});
|
});
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
export { RenderRoot, MIN_PAGE_WIDTH } from './RenderRoot';
|
|
||||||
export * from './render-block';
|
|
||||||
export * from './hooks';
|
|
||||||
|
|
||||||
export { RenderBlock } from './render-block';
|
|
||||||
|
|
||||||
export * from './recast-block';
|
|
||||||
export * from './recast-block/types';
|
|
||||||
|
|
||||||
export * from './block-pendant';
|
export * from './block-pendant';
|
||||||
|
export { useEditor } from './Contexts';
|
||||||
|
export * from './editor';
|
||||||
|
export * from './hooks';
|
||||||
export * from './kanban';
|
export * from './kanban';
|
||||||
export * from './kanban/types';
|
export * from './kanban/types';
|
||||||
|
export * from './recast-block';
|
||||||
|
export * from './recast-block/types';
|
||||||
|
export {
|
||||||
|
BlockRenderProvider,
|
||||||
|
RenderBlockChildren,
|
||||||
|
useBlockRender,
|
||||||
|
withTreeViewChildren,
|
||||||
|
} from './render-block';
|
||||||
|
export { MIN_PAGE_WIDTH, RenderRoot } from './RenderRoot';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
|
|
||||||
export * from './editor';
|
|
||||||
|
|
||||||
export { useEditor } from './Contexts';
|
|
||||||
|
@ -10,6 +10,8 @@ import {
|
|||||||
RecastMetaProperty,
|
RecastMetaProperty,
|
||||||
RecastPropertyId,
|
RecastPropertyId,
|
||||||
} from '../recast-block/types';
|
} from '../recast-block/types';
|
||||||
|
import { BlockRenderProvider } from '../render-block';
|
||||||
|
import { KanbanBlockRender } from '../render-block/RenderKanbanBlock';
|
||||||
import { useInitKanbanEffect, useRecastKanban } from './kanban';
|
import { useInitKanbanEffect, useRecastKanban } from './kanban';
|
||||||
import { KanbanGroup } from './types';
|
import { KanbanGroup } from './types';
|
||||||
|
|
||||||
@ -54,9 +56,11 @@ export const KanbanProvider = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<BlockRenderProvider blockRender={KanbanBlockRender}>
|
||||||
<KanbanContext.Provider value={value}>
|
<KanbanContext.Provider value={value}>
|
||||||
{children}
|
{children}
|
||||||
</KanbanContext.Provider>
|
</KanbanContext.Provider>
|
||||||
|
</BlockRenderProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
35
libs/components/editor-core/src/render-block/Context.tsx
Normal file
35
libs/components/editor-core/src/render-block/Context.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { genErrorObj } from '@toeverything/utils';
|
||||||
|
import { createContext, PropsWithChildren, useContext } from 'react';
|
||||||
|
import { RenderBlockProps } from './RenderBlock';
|
||||||
|
|
||||||
|
type BlockRenderProps = {
|
||||||
|
blockRender: (args: RenderBlockProps) => JSX.Element | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const BlockRenderContext = createContext<BlockRenderProps>(
|
||||||
|
genErrorObj(
|
||||||
|
'Failed to get BlockChildrenContext! The context only can use under the "render-root"'
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
) as any
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CAUTION! DO NOT PROVIDE A DYNAMIC BLOCK RENDER!
|
||||||
|
*/
|
||||||
|
export const BlockRenderProvider = ({
|
||||||
|
blockRender,
|
||||||
|
children,
|
||||||
|
}: PropsWithChildren<BlockRenderProps>) => {
|
||||||
|
return (
|
||||||
|
<BlockRenderContext.Provider value={{ blockRender }}>
|
||||||
|
{children}
|
||||||
|
</BlockRenderContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useBlockRender = () => {
|
||||||
|
const { blockRender } = useContext(BlockRenderContext);
|
||||||
|
return {
|
||||||
|
BlockRender: blockRender,
|
||||||
|
};
|
||||||
|
};
|
@ -4,7 +4,12 @@ import { useCallback, useMemo } from 'react';
|
|||||||
import { useEditor } from '../Contexts';
|
import { useEditor } from '../Contexts';
|
||||||
import { useBlock } from '../hooks';
|
import { useBlock } from '../hooks';
|
||||||
|
|
||||||
interface RenderBlockProps {
|
/**
|
||||||
|
* Render nothing
|
||||||
|
*/
|
||||||
|
export const NullBlockRender = (): null => null;
|
||||||
|
|
||||||
|
export interface RenderBlockProps {
|
||||||
blockId: string;
|
blockId: string;
|
||||||
hasContainer?: boolean;
|
hasContainer?: boolean;
|
||||||
}
|
}
|
||||||
@ -29,7 +34,7 @@ export function RenderBlock({
|
|||||||
if (block?.type) {
|
if (block?.type) {
|
||||||
return editor.getView(block.type).View;
|
return editor.getView(block.type).View;
|
||||||
}
|
}
|
||||||
return () => null;
|
return (): null => null;
|
||||||
}, [editor, block?.type]);
|
}, [editor, block?.type]);
|
||||||
|
|
||||||
if (!block) {
|
if (!block) {
|
||||||
@ -64,4 +69,5 @@ export function RenderBlock({
|
|||||||
|
|
||||||
const BlockContainer = styled('div')(({ theme }) => ({
|
const BlockContainer = styled('div')(({ theme }) => ({
|
||||||
fontSize: theme.typography.body1.fontSize,
|
fontSize: theme.typography.body1.fontSize,
|
||||||
|
flex: 1,
|
||||||
}));
|
}));
|
||||||
|
@ -1,16 +1,39 @@
|
|||||||
|
import { styled } from '@toeverything/components/ui';
|
||||||
import type { AsyncBlock } from '../editor';
|
import type { AsyncBlock } from '../editor';
|
||||||
import { RenderBlock } from './RenderBlock';
|
import { useBlockRender } from './Context';
|
||||||
|
import { NullBlockRender } from './RenderBlock';
|
||||||
|
|
||||||
interface RenderChildrenProps {
|
export interface RenderChildrenProps {
|
||||||
block: AsyncBlock;
|
block: AsyncBlock;
|
||||||
|
indent?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RenderBlockChildren = ({
|
||||||
|
block,
|
||||||
|
indent = true,
|
||||||
|
}: RenderChildrenProps) => {
|
||||||
|
const { BlockRender } = useBlockRender();
|
||||||
|
if (BlockRender === NullBlockRender) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RenderBlockChildren = ({ block }: RenderChildrenProps) => {
|
|
||||||
return block.childrenIds.length ? (
|
return block.childrenIds.length ? (
|
||||||
<>
|
<StyledIdentWrapper indent={indent}>
|
||||||
{block.childrenIds.map(childId => {
|
{block.childrenIds.map(childId => {
|
||||||
return <RenderBlock key={childId} blockId={childId} />;
|
return <BlockRender key={childId} blockId={childId} />;
|
||||||
})}
|
})}
|
||||||
</>
|
</StyledIdentWrapper>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indent rendering child nodes
|
||||||
|
*/
|
||||||
|
const StyledIdentWrapper = styled('div')<{ indent?: boolean }>(
|
||||||
|
({ indent }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
// TODO: marginLeft should use theme provided by styled
|
||||||
|
...(indent && { marginLeft: '30px' }),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
import { styled } from '@toeverything/components/ui';
|
||||||
|
import { useBlock } from '../hooks';
|
||||||
|
import { BlockRenderProvider } from './Context';
|
||||||
|
import { NullBlockRender, RenderBlock, RenderBlockProps } from './RenderBlock';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render block without children.
|
||||||
|
*/
|
||||||
|
const BlockWithoutChildrenRender = ({ blockId }: RenderBlockProps) => {
|
||||||
|
return (
|
||||||
|
<BlockRenderProvider blockRender={NullBlockRender}>
|
||||||
|
<RenderBlock blockId={blockId} />
|
||||||
|
</BlockRenderProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a block, but only one level of children.
|
||||||
|
*/
|
||||||
|
const OneLevelBlockRender = ({ blockId }: RenderBlockProps) => {
|
||||||
|
return (
|
||||||
|
<BlockRenderProvider blockRender={BlockWithoutChildrenRender}>
|
||||||
|
<RenderBlock blockId={blockId} />
|
||||||
|
</BlockRenderProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const KanbanBlockRender = ({ blockId }: RenderBlockProps) => {
|
||||||
|
const { block } = useBlock(blockId);
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
return (
|
||||||
|
<BlockRenderProvider blockRender={NullBlockRender}>
|
||||||
|
<RenderBlock blockId={blockId} />
|
||||||
|
</BlockRenderProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BlockRenderProvider blockRender={NullBlockRender}>
|
||||||
|
<RenderBlock blockId={blockId} />
|
||||||
|
{block?.childrenIds.map(childId => (
|
||||||
|
<StyledBorder key={childId}>
|
||||||
|
<RenderBlock blockId={childId} />
|
||||||
|
</StyledBorder>
|
||||||
|
))}
|
||||||
|
</BlockRenderProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledBorder = styled('div')({
|
||||||
|
border: '1px solid #E0E6EB',
|
||||||
|
borderRadius: '5px',
|
||||||
|
margin: '4px',
|
||||||
|
padding: '0 4px',
|
||||||
|
});
|
@ -1,10 +1,3 @@
|
|||||||
import {
|
|
||||||
BlockPendantProvider,
|
|
||||||
CreateView,
|
|
||||||
RenderBlock,
|
|
||||||
useCurrentView,
|
|
||||||
useOnSelect,
|
|
||||||
} from '@toeverything/components/editor-core';
|
|
||||||
import { styled } from '@toeverything/components/ui';
|
import { styled } from '@toeverything/components/ui';
|
||||||
import type {
|
import type {
|
||||||
ComponentPropsWithoutRef,
|
ComponentPropsWithoutRef,
|
||||||
@ -12,9 +5,10 @@ import type {
|
|||||||
CSSProperties,
|
CSSProperties,
|
||||||
ReactElement,
|
ReactElement,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { forwardRef, useState } from 'react';
|
import { forwardRef } from 'react';
|
||||||
import { SCENE_CONFIG } from '../blocks/group/config';
|
import { CreateView } from '../editor';
|
||||||
import { BlockContainer } from '../components/BlockContainer';
|
import { useBlockRender } from './Context';
|
||||||
|
import { NullBlockRender } from './RenderBlock';
|
||||||
|
|
||||||
type WithChildrenConfig = {
|
type WithChildrenConfig = {
|
||||||
indent: CSSProperties['marginLeft'];
|
indent: CSSProperties['marginLeft'];
|
||||||
@ -41,45 +35,6 @@ const TreeView = forwardRef<
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
interface ChildrenViewProp {
|
|
||||||
childrenIds: string[];
|
|
||||||
handleCollapse: () => void;
|
|
||||||
indent?: string | number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ChildrenView = ({
|
|
||||||
childrenIds,
|
|
||||||
handleCollapse,
|
|
||||||
indent,
|
|
||||||
}: ChildrenViewProp) => {
|
|
||||||
const [currentView] = useCurrentView();
|
|
||||||
const isKanbanScene = currentView.type === SCENE_CONFIG.KANBAN;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Children style={{ ...(!isKanbanScene && { marginLeft: indent }) }}>
|
|
||||||
{childrenIds.map((childId, idx) => {
|
|
||||||
if (isKanbanScene) {
|
|
||||||
return (
|
|
||||||
<StyledBorder key={childId}>
|
|
||||||
<RenderBlock blockId={childId} />
|
|
||||||
</StyledBorder>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TreeView
|
|
||||||
key={childId}
|
|
||||||
lastItem={idx === childrenIds.length - 1}
|
|
||||||
onClick={handleCollapse}
|
|
||||||
>
|
|
||||||
<RenderBlock key={childId} blockId={childId} />
|
|
||||||
</TreeView>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Children>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const CollapsedNode = forwardRef<
|
const CollapsedNode = forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
ComponentPropsWithoutRef<'div'>
|
ComponentPropsWithoutRef<'div'>
|
||||||
@ -104,15 +59,15 @@ export const withTreeViewChildren = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (props: CreateView) => {
|
return (props: CreateView) => {
|
||||||
const { block, editor } = props;
|
const { block } = props;
|
||||||
|
const { BlockRender } = useBlockRender();
|
||||||
const collapsed = block.getProperty('collapsed')?.value;
|
const collapsed = block.getProperty('collapsed')?.value;
|
||||||
const childrenIds = block.childrenIds;
|
const childrenIds = block.childrenIds;
|
||||||
const showChildren = !collapsed && childrenIds.length > 0;
|
const showChildren =
|
||||||
|
!collapsed &&
|
||||||
|
childrenIds.length > 0 &&
|
||||||
|
BlockRender !== NullBlockRender;
|
||||||
|
|
||||||
const [isSelect, setIsSelect] = useState<boolean>(false);
|
|
||||||
useOnSelect(block.id, (isSelect: boolean) => {
|
|
||||||
setIsSelect(isSelect);
|
|
||||||
});
|
|
||||||
const handleCollapse = () => {
|
const handleCollapse = () => {
|
||||||
block.setProperty('collapsed', { value: true });
|
block.setProperty('collapsed', { value: true });
|
||||||
};
|
};
|
||||||
@ -122,15 +77,8 @@ export const withTreeViewChildren = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BlockContainer
|
<>
|
||||||
editor={props.editor}
|
{creator(props)}
|
||||||
block={block}
|
|
||||||
selected={isSelect}
|
|
||||||
className={Wrapper.toString()}
|
|
||||||
>
|
|
||||||
<BlockPendantProvider block={block}>
|
|
||||||
<div>{creator(props)}</div>
|
|
||||||
</BlockPendantProvider>
|
|
||||||
|
|
||||||
{collapsed && (
|
{collapsed && (
|
||||||
<CollapsedNode
|
<CollapsedNode
|
||||||
@ -138,22 +86,24 @@ export const withTreeViewChildren = (
|
|||||||
style={{ marginLeft: config.indent }}
|
style={{ marginLeft: config.indent }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showChildren && (
|
{showChildren &&
|
||||||
<ChildrenView
|
childrenIds.map((childId, idx) => {
|
||||||
childrenIds={childrenIds}
|
return (
|
||||||
handleCollapse={handleCollapse}
|
<TreeView
|
||||||
indent={config.indent}
|
key={childId}
|
||||||
/>
|
lastItem={idx === childrenIds.length - 1}
|
||||||
)}
|
onClick={handleCollapse}
|
||||||
</BlockContainer>
|
style={{ marginLeft: config.indent }}
|
||||||
|
>
|
||||||
|
<BlockRender key={childId} blockId={childId} />
|
||||||
|
</TreeView>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const Wrapper = styled('div')({ display: 'flex', flexDirection: 'column' });
|
|
||||||
|
|
||||||
const Children = Wrapper;
|
|
||||||
|
|
||||||
const TREE_COLOR = '#D5DFE6';
|
const TREE_COLOR = '#D5DFE6';
|
||||||
// adjust left and right margins of the the tree line
|
// adjust left and right margins of the the tree line
|
||||||
const TREE_LINE_LEFT_OFFSET = '-16px';
|
const TREE_LINE_LEFT_OFFSET = '-16px';
|
||||||
@ -163,6 +113,7 @@ const TREE_LINE_WIDTH = '12px';
|
|||||||
|
|
||||||
const TreeWrapper = styled('div')({
|
const TreeWrapper = styled('div')({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
});
|
});
|
||||||
|
|
||||||
const StyledTreeView = styled('div')({
|
const StyledTreeView = styled('div')({
|
||||||
@ -228,9 +179,3 @@ const LastItemRadius = styled('div')({
|
|||||||
borderRadius: '0 0 0 3px',
|
borderRadius: '0 0 0 3px',
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
});
|
});
|
||||||
|
|
||||||
const StyledBorder = styled('div')({
|
|
||||||
border: '1px solid #E0E6EB',
|
|
||||||
borderRadius: '5px',
|
|
||||||
margin: '4px',
|
|
||||||
});
|
|
@ -1,2 +1,4 @@
|
|||||||
|
export { BlockRenderProvider, useBlockRender } from './Context';
|
||||||
export * from './RenderBlock';
|
export * from './RenderBlock';
|
||||||
export * from './RenderBlockChildren';
|
export * from './RenderBlockChildren';
|
||||||
|
export { withTreeViewChildren } from './WithTreeViewChildren';
|
||||||
|
Loading…
Reference in New Issue
Block a user