-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lexical-rich-text][lexical-playground][lexical-react]: Update selection when something is selected inside a DecoratorNode #7072
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,6 @@ import { | |
$isNodeSelection, | ||
$isRangeSelection, | ||
$setSelection, | ||
CLICK_COMMAND, | ||
COMMAND_PRIORITY_LOW, | ||
createCommand, | ||
DRAGSTART_COMMAND, | ||
|
@@ -300,11 +299,6 @@ export default function ImageComponent({ | |
}, | ||
COMMAND_PRIORITY_LOW, | ||
), | ||
editor.registerCommand<MouseEvent>( | ||
CLICK_COMMAND, | ||
onClick, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not removing the onClick handler because it's used for the right button. See #5056 |
||
COMMAND_PRIORITY_LOW, | ||
), | ||
editor.registerCommand<MouseEvent>( | ||
RIGHT_CLICK_IMAGE_COMMAND, | ||
onClick, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,7 @@ import { | |
} from '@lexical/utils'; | ||
import { | ||
$applyNodeReplacement, | ||
$createNodeSelection, | ||
$createParagraphNode, | ||
$createRangeSelection, | ||
$createTabNode, | ||
|
@@ -565,13 +566,25 @@ export function registerRichText(editor: LexicalEditor): () => void { | |
const removeListener = mergeRegister( | ||
editor.registerCommand( | ||
CLICK_COMMAND, | ||
(payload) => { | ||
const selection = $getSelection(); | ||
if ($isNodeSelection(selection)) { | ||
selection.clear(); | ||
return true; | ||
(event) => { | ||
if (!(event.target instanceof Element)) { | ||
return false; | ||
} | ||
return false; | ||
const decorator = event.target.closest( | ||
'[data-lexical-decorator="true"]', | ||
); | ||
if (!decorator) { | ||
return false; | ||
} | ||
editor.update(() => { | ||
const node = $getNearestNodeFromDOMNode(decorator); | ||
if ($isDecoratorNode(node)) { | ||
const selection = $createNodeSelection(); | ||
selection.add(node.getKey()); | ||
$setSelection(selection); | ||
} | ||
Comment on lines
+581
to
+585
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a breaking change because now it works differently and only one node can be selected, where before you could select multiple nodes. This is also a bit tricky to override without having its own command. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For me this is more of a bug fix than a breaking change. Currently the selection was being set to null which is definitely worse and doesn't make much sense. Probably many people haven't noticed this because the most used nodes like ImageNode fix the behavior with their commands.
From the frontend (let's say the playground), I know how to select multiple nodes with a rangeSelection, but I don't know of any way I could select multiple nodes with a NodeSelection, neither before nor after this PR. I think that it's a good thing, since I don't know in what scenario someone would want something like that.
Same as above. I don't see this PR changing anything in that regard. Customizing the behavior used to require a command, now it does too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get that this behavior makes more sense but it’s probably not backwards compatible, anyone upgrading to this PR is going to have to audit their code to be compliant. Without a backwards compatible upgrade path it might be tricky or at least take longer to get meta to accept it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To select multiple nodes with a NodeSelection you click one and then shift-click the others. They don't even have to be adjacent. Try creating three divider nodes, click the first one, and then shift-click the third one. I don't think this makes a lot of sense to do for this particular kind of node, but it's how the editor works now and changing that would break compatibility. The tricky thing about breaking compatibility is we don't know what we don't know. The unit and e2e test don't even come close to covering what people are doing in their own projects. Based on the scope of this affecting events for all decorators I think this would require at least some Meta folks looking closely at how all of their projects are using events and decorators. If we're going to just patch the problem I suspect there's a way we can do it that just brings Firefox behavior in alignment with the other platforms and doesn't change anything fundamental. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, it makes sense! 👌👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm making a PR in our codebase to fix this on our end. |
||
}); | ||
return true; | ||
}, | ||
0, | ||
), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -786,7 +786,7 @@ export class LexicalEditor { | |
* deterministically in the order of registration. | ||
* | ||
* @param command - the command that will trigger the callback. | ||
* @param listener - the function that will execute when the command is dispatched. | ||
* @param listener - the function that will execute when the command is dispatched. Returns true to stop propagation, false to continue. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgive me for this change that is irrelevant to the objective of the PR. But I always have to think about what true and false mean 😅 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a common source of confusion 👍 |
||
* @param priority - the relative priority of the listener. 0 | 1 | 2 | 3 | 4 | ||
* (or {@link COMMAND_PRIORITY_EDITOR} | | ||
* {@link COMMAND_PRIORITY_LOW} | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even considering that double click was allowed, it's odd that the container was a button, and the button a div.
It was confusing to understand the click command I was deleting until I realized this (I thought buttonRef was the small button)