Replies: 4 comments
-
i saw this discussion but doesn't seem to help me either.. #2553 I also want this functionality. I was about to start my own discussion but found this one I want to be able to selectively choose which text formatting styles to remove on paste of text.. Ive tried registering command with different priorities but it doesnt format the text after paste. Ive also tried using a transform to do this but it runs before the text is in the editor.. meaning that only text that is already in the editor gets transformed. I looked at the past command in the code snippet: editor.registerCommand(
PASTE_COMMAND,
(event) => {
const [, files, hasTextContent] = eventFiles(event);
if (files.length > 0 && !hasTextContent) {
editor.dispatchCommand(DRAG_DROP_PASTE, files);
return true;
}
// if inputs then paste within the input ignore creating a new node on paste event
if (isSelectionCapturedInDecoratorInput(event.target as Node)) {
return false;
}
const selection = $getSelection();
if (
$isRangeSelection(selection) ||
DEPRECATED_$isGridSelection(selection)
) {
onPasteForRichText(event, editor);
return true;
}
return false;
},
COMMAND_PRIORITY_EDITOR,
), is there a way to hook into this? or can a way be provided to hook into formatting the rich text before it is put into the editor or reliably select text after paste to format the selection? Thanks in advance! Additional note:
__ Im not sure if i provided enough context but feel free to ask further questions for clarification |
Beta Was this translation helpful? Give feedback.
-
i read the code a bit more and saw that it is being tagged with so i wrote this code which is now able to react to the paste..but now i need to figure out how to only format the pasted text see sample below non-optimal code:
but i think im on the right track i now need to figure out:
|
Beta Was this translation helpful? Give feedback.
-
v2 import { useEffect } from 'react';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { $patchStyleText } from '@lexical/selection';
import { $createRangeSelection, $getRoot } from 'lexical';
const $createFullContentSelection = () => {
const allContentSelection = $createRangeSelection();
const textNodes = $getRoot().getAllTextNodes();
const firstNode = textNodes[0];
const lastNode = textNodes.at(-1);
if (firstNode && lastNode) {
allContentSelection.setTextNodeRange(
firstNode,
0,
lastNode,
lastNode?.getTextContentSize(),
);
}
return allContentSelection;
};
export function ContentPastePlugin() {
const [editor] = useLexicalComposerContext();
useEffect(() => {
return editor.registerUpdateListener((listener) => {
if (!listener.tags.has('paste')) return;
editor.update(() => {
const selection = $createFullContentSelection();
$patchStyleText(selection, { color: null });
});
});
}, [editor]);
return null;
} still not there yet but works |
Beta Was this translation helpful? Give feedback.
-
v3:
import { useEffect } from 'react';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { $copyNode, $getNodeByKey, $isTextNode } from 'lexical';
function cssStringToMap(cssString: string): Map<string, string> {
const cssMap = new Map<string, string>();
const declarations = cssString.split(';');
for (const declaration of declarations) {
const [property, value] = declaration.split(':');
if (property && value) {
cssMap.set(property.trim(), value.trim());
}
}
return cssMap;
}
function mapToCssString(cssMap: Map<string, string>): string {
let cssString = '';
for (const [property, value] of cssMap.entries()) {
cssString += `${property}: ${value};`;
}
return cssString;
}
const SUPPORTED_NODE_TYPES = ['text'];
export function ContentPastePlugin() {
const [editor] = useLexicalComposerContext();
useEffect(() => {
return editor.registerUpdateListener((listener) => {
if (!listener.tags.has('paste')) return;
editor.update(() => {
listener.dirtyLeaves.forEach((key) => {
const node = $getNodeByKey(key);
if (!node || !SUPPORTED_NODE_TYPES.includes(node?.getType() ?? '')) return;
const copy = $copyNode(node);
if ($isTextNode(copy)) {
const cssMap = cssStringToMap(node.getStyle() ?? '');
const stylesLength = cssMap.size;
// if(cssMap.has('color')) is not necessary
// just to demonstrate there can be conditions here to
// decide if the style should be removed or not
if(cssMap.has('color')) cssMap.delete('color');
if (stylesLength !== cssMap.size) {
copy.setStyle(mapToCssString(cssMap));
node.replace(copy);
}
}
});
});
});
}, [editor]);
return null;
} Caveats:
https://lexical.dev/docs/concepts/listeners#registerupdatelistener
|
Beta Was this translation helpful? Give feedback.
-
Hi everyone !
First of all thanks for the awesome library.
I was wondering if there is a way to force a certain style on paste of a text. Aka, let's say I would paste a text colored in blue and left aligned in the editor. And I would like this text to instantly appear green, bold and centered as I paste it. Ideally I'd like to also prevent the user to un-bold it by using cmd+b for instance. I'd also like that any subsequent typing get the same style applied (green bold centered).
I've thought of different approaches :
Some of these don't achieve every requirements I mentioned, and some others seem slightly overkill.
Does anyone has an idea on which would be the optimal way of achieving this ?
Thanks a lot!
Beta Was this translation helpful? Give feedback.
All reactions