Skip to content

Commit

Permalink
添加卡片前后节点支持,优化表格溢出处理逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
chenshuai2144 committed Nov 6, 2024
1 parent 62855d8 commit e14fd69
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 30 deletions.
23 changes: 23 additions & 0 deletions src/MarkdownEditor/editor/elements/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,29 @@ export const MElement = (props: RenderElementProps) => {
return <FootnoteDefinition {...props} />;
case 'footnoteReference':
return <FootnoteReference {...props} />;
case 'card-before':
return (
<span
style={{
minWidth: 2,
}}
{...props.attributes}
>
{props.children}
</span>
);
case 'card-after':
return (
<span
style={{
minWidth: 2,
alignSelf: 'end',
}}
{...props.attributes}
>
{props.children}
</span>
);
default:
return <Paragraph {...props} />;
}
Expand Down
118 changes: 93 additions & 25 deletions src/MarkdownEditor/editor/elements/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const Table = observer((props: RenderElementProps) => {
});

const tableRef = React.useRef<NodeEntry<TableNode>>();
const overflowShadowContainerRef = React.useRef<HTMLTableElement>(null);
const tableCellRef = useRef<NodeEntry<TableCellNode>>();

useEffect(() => {
Expand Down Expand Up @@ -141,48 +142,115 @@ export const Table = observer((props: RenderElementProps) => {
}
}
}, [store.tableCellNode, store.editor, setState]);
const tableTargetRef = useRef<HTMLTableElement>(null);
useEffect(() => {
if (!tableTargetRef.current) {
return;
}
const observerRoot = (tableTargetRef as any).current?.parentNode;
const observerTarget = (tableTargetRef as any).current;
const overflowShadowContainer = overflowShadowContainerRef.current!;
overflowShadowContainer.classList.add('overflow-shadow-container');
overflowShadowContainer.classList.add('card-table-wrap');
const options = {
root: observerRoot,
threshold: 1,
};

new IntersectionObserver(([entry]) => {
if (entry.intersectionRatio !== 1) {
overflowShadowContainer.classList.add(
'is-overflowing',
'is-scrolled-left',
);
} else {
overflowShadowContainer.classList.remove('is-overflowing');
}
}, options).observe(observerTarget);

let handleScrollX = (e: any) => {
if (e.target.scrollLeft < 1) {
overflowShadowContainer.classList.add('is-scrolled-left');
} else {
overflowShadowContainer.classList.remove('is-scrolled-left');
}
if (
Math.abs(
e.target.scrollLeft +
e.target.offsetWidth -
observerTarget.offsetWidth,
) <= 1
) {
overflowShadowContainer.classList.add('is-scrolled-right');
} else {
overflowShadowContainer.classList.remove('is-scrolled-right');
}
};

observerRoot.addEventListener('scroll', handleScrollX);

return () => {
observerRoot.removeEventListener('scroll', handleScrollX);
};
}, []);
return useMemo(() => {
const [pre, ...row] = props.children;
const after = row.pop();

return (
<div
className={'ant-md-editor-drag-el ant-md-editor-table'}
{...props.attributes}
data-be={'table'}
onDragStart={store.dragStart}
onMouseUp={handleClickTable}
ref={overflowShadowContainerRef}
style={{
maxWidth: '100%',
...(store.editor?.children?.length === 1
? {}
: {
border: '1px solid #e8e8e8',
borderRadius: 16,
}),
display: 'flex',
gap: 1,
}}
>
{store.tableAttrVisible && (
<TableAttr
state={state}
setState={setState}
tableRef={tableRef}
tableCellRef={tableCellRef}
/>
)}
<DragHandle />
{pre}
<div
className={'ant-md-editor-drag-el ant-md-editor-table'}
style={{
width: '100%',
borderCollapse: 'collapse',
tableLayout: 'fixed',
borderSpacing: 0,
maxWidth: '100%',
overflow: 'auto',
...(store.editor?.children?.length === 1
? {}
: {
border: '1px solid #e8e8e8',
borderRadius: 16,
}),
}}
>
<table>
<tbody>{props.children}</tbody>
</table>
{store.tableAttrVisible && (
<TableAttr
state={state}
setState={setState}
tableRef={tableRef}
tableCellRef={tableCellRef}
/>
)}
<DragHandle />

<div
style={{
width: '100%',
maxWidth: '100%',
overflow: 'auto',
}}
>
<table
style={{
borderCollapse: 'collapse',
borderSpacing: 0,
}}
ref={tableTargetRef}
>
<tbody>{row}</tbody>
</table>
</div>
</div>
{after}
</div>
);
}, [
Expand Down
12 changes: 11 additions & 1 deletion src/MarkdownEditor/editor/parser/parserMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,17 @@ const parseTableOrChart = (

const node: TableNode | ChartNode = {
type: isChart ? 'chart' : 'table',
children,
children: [
{
type: 'card-before',
children: [{ text: '' }],
},
...children,
{
type: 'card-after',
children: [{ text: '' }],
},
],
otherProps,
};
return node;
Expand Down
19 changes: 19 additions & 0 deletions src/MarkdownEditor/editor/plugins/hotKeyCommands/enter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,25 @@ export class EnterKey {
});
if (node) {
let [el, path] = node;

if (el.type === 'card-before') {
Transforms.insertNodes(this.editor, EditorUtils.p, {
at: Path.parent(path),
select: true,
});
e.preventDefault();
return;
}

if (el.type === 'card-after') {
console.log(Path.parent(path));
Transforms.insertNodes(this.editor, EditorUtils.p, {
at: Path.next(Path.parent(path)),
select: true,
});
e.preventDefault();
return;
}
switch (el.type as NodeTypes) {
case 'table-cell':
e.preventDefault();
Expand Down
29 changes: 27 additions & 2 deletions src/MarkdownEditor/editor/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { Editor, Node, Path, Transforms } from 'slate';
import { Editor, Node, Path, Range, Transforms } from 'slate';

export const inlineNode = new Set(['break']);

const voidNode = new Set(['hr', 'break']);

function hasRange(editor: Editor, range: { anchor: any; focus: any }): boolean {
const { anchor, focus } = range;
return (
Editor.hasPath(editor, anchor.path) && Editor.hasPath(editor, focus.path)
);
}

/**
* 为编辑器添加 Markdown 支持的插件。
*
Expand All @@ -25,7 +32,7 @@ const voidNode = new Set(['hr', 'break']);
* 该插件还根据 `store.manual` 的值决定是否手动处理某些操作。
*/
export const withMarkdown = (editor: Editor) => {
const { isInline, isVoid, apply } = editor;
const { isInline, isVoid, apply, deleteBackward } = editor;

editor.isInline = (element) => {
return inlineNode.has(element.type) || isInline(element);
Expand Down Expand Up @@ -157,5 +164,23 @@ export const withMarkdown = (editor: Editor) => {
apply(operation);
};

editor.deleteBackward = (unit: any) => {
const { selection } = editor;

if (
selection &&
hasRange(editor, selection) &&
Range.isCollapsed(selection)
) {
const node = Node.get(editor, Path.parent(selection.anchor.path));
if (node.type === 'card-before' || node.type === 'card-after') {
return;
}
}

console.log('deleteBackward', unit);
deleteBackward(unit);
};

return editor;
};
6 changes: 6 additions & 0 deletions src/MarkdownEditor/editor/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ const genStyle: GenerateStyle<ChatTokenType> = (token) => {
'th:last-child,td:last-child': {
borderRight: 'none',
},
'th:last-child': {
borderTopRightRadius: 16,
},
'th:first-child': {
borderTopLeftRadius: 16,
},
'tr:last-child th,tr:last-child td': {
borderBottom: 'none',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const ReadonlyBaseBar = observer(
const listDom = useMemo(() => {
let list = [];

if (store?.editorProps?.comment?.enable) {
if (store?.editorProps?.comment?.onSubmit) {
list.push(
<div
role="button"
Expand Down
12 changes: 11 additions & 1 deletion src/MarkdownEditor/el.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,20 @@ export type FootnoteDefinitionNode<T = Record<string, any>> = {
h?: number;
};

export type CardBeforeNode = {
type: 'card-before';
children: BaseElement['children'];
};

export type CardAfterNode = {
type: 'card-after';
children: BaseElement['children'];
};

export type TableNode<T = Record<string, any>> = {
contextProps?: T;
type: 'table';
children: TableRowNode[];
children: (TableRowNode | CardBeforeNode | CardAfterNode)[];
otherProps?: {
showSource?: boolean;
config: ChartTypeConfig | ChartTypeConfig[];
Expand Down
34 changes: 34 additions & 0 deletions src/MarkdownEditor/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,37 @@
right: -7px;
pointer-events: all;
}

.markdown-editor .overflow-shadow-container::before,
.markdown-editor .overflow-shadow-container::after {
content: '';
position: absolute;
top: 13px;
bottom: 8px;
width: 10px;
opacity: 0;
transition: opacity 0.1s;
z-index: 100;
pointer-events: none;
user-select: none;
height: calc(100% - 32px);
}

.markdown-editor .overflow-shadow-container::after {
right: -4px;
background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1));
}

.markdown-editor
.overflow-shadow-container.is-overflowing:not(.is-scrolled-right)::after {
opacity: 1;
}

.markdown-editor
.overflow-shadow-container.is-overflowing:not(.is-scrolled-left)::before {
opacity: 1;
}
.markdown-editor .overflow-shadow-container::before {
left: 3px;
background: linear-gradient(to left, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1));
}

1 comment on commit e14fd69

@vercel
Copy link

@vercel vercel bot commented on e14fd69 Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.