Skip to content

Commit

Permalink
feat: node copy with button
Browse files Browse the repository at this point in the history
  • Loading branch information
MasanobuRyuman committed Jun 13, 2023
1 parent 89f8748 commit d458635
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { style } from '@vanilla-extract/css';
import Element, * as elements from './element';
import * as logger from './logger';
import * as error from './error';
import Node from './node';
import * as Node from './node';
import Path, * as pathHelpers from './path';
import ReactEditor from './reactEditor';
import * as transforms from './transform';
Expand Down
19 changes: 18 additions & 1 deletion packages/core/src/helpers/node/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
import { Node as SlateNode } from 'slate';
import { Editor, Node as SlateNode } from 'slate';

export default SlateNode;

export const copyNode = async (editor: Editor) => {
const dataTransfer = new DataTransfer();
editor.setFragmentData(dataTransfer, 'copy');
const clipboardBlobList = dataTransfer.types.map((type) => {
return new Blob([dataTransfer.getData(type)], { type: type });
});

const clipBoardItem: Record<string, Blob> = {};
const removeType = 'application/x-slate-fragment';
clipboardBlobList
.filter((value) => value.type !== removeType)
.forEach((blob) => {
clipBoardItem[blob.type] = blob;
});
await navigator.clipboard.write([new ClipboardItem(clipBoardItem)]);
};
44 changes: 36 additions & 8 deletions packages/core/src/toolmenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useCallback } from 'react';
import { Node, Path } from 'slate';
import { Element, Node, Path } from 'slate';
import { useSlate } from 'slate-react';
import { CopyIcon } from '../components/icons/copy';
import { DustboxIcon } from '../components/icons/dustbox';
import { styles } from './index.css';
import { Text } from 'slate';
import { helpers } from '../helpers';

export type ToolmenuProps = {
path: Path;
Expand All @@ -19,13 +21,39 @@ export const Toolmenu: React.FC<ToolmenuProps> = ({ path, onDone }) => {
onDone();
}, [editor, path, onDone]);

const handleCopyClick = useCallback(() => {
const node = Node.get(editor, path);
// TODO: There seems to be no API for copying. Replace this workaround if any found.
const copiedNode = JSON.parse(JSON.stringify(node));
editor.insertNodes(copiedNode, {
at: Path.next(path),
});
const handleCopyClick = useCallback(async () => {
const selection = editor.selection;
if (!selection || selection.anchor.offset === selection.focus.offset) {
const node = Node.get(editor, path);
if (!Element.isElement(node)) return;
const lastChildIndex = node.children.length - 1;
const lastNode = node.children[lastChildIndex];
if (!Text.isText(lastNode)) return;
const lastOffset = lastNode.text.length;
editor.selection = {
anchor: {
path: [...path, 0],
offset: 0,
},
focus: {
path: [...path, lastChildIndex],
offset: lastOffset,
},
};
await helpers.Node.copyNode(editor);
editor.selection = {
anchor: {
path: [...path, 0],
offset: 0,
},
focus: {
path: [...path, 0],
offset: 0,
},
};
} else {
helpers.Node.copyNode(editor);
}
onDone();
}, [editor, path, onDone]);

Expand Down

0 comments on commit d458635

Please sign in to comment.