Skip to content

[lexical] Deprecate CAN_UNDO_COMMAND and CAN_REDO_COMMAND in favour of HistoryExtension's signals - #8918

Open
LeSingh1 wants to merge 1 commit into
facebook:mainfrom
LeSingh1:fix/clear-editor-can-undo-redo
Open

[lexical] Deprecate CAN_UNDO_COMMAND and CAN_REDO_COMMAND in favour of HistoryExtension's signals#8918
LeSingh1 wants to merge 1 commit into
facebook:mainfrom
LeSingh1:fix/clear-editor-can-undo-redo

Conversation

@LeSingh1

@LeSingh1 LeSingh1 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

Per the review: CAN_UNDO_COMMAND and CAN_REDO_COMMAND are deprecated in favour of HistoryExtension's canUndo / canRedo signals.

A command only reports a change. A listener registered after the editor is initialized never sees the current value and has no way to read it, so there is no correct way to bootstrap a toolbar button from these commands. The signals are derived from the history stacks by syncFromHistoryState and always hold the current value.

  • @deprecated JSDoc on both commands, pointing at the signals.
  • @lexical/history README: an "Undo/redo availability" section with a React example using useExtensionSignalValue, and a non-React one reading the signal via getExtensionDependencyFromEditor.

The commands are still dispatched, matching how KEY_MODIFIER_COMMAND was handled.

Test plan

Docs and JSDoc only — nothing to test. tsc --noEmit clean, prettier and eslint clean. No deprecation lint rule in the repo, and KEY_MODIFIER_COMMAND is still dispatched internally while deprecated, so no call sites needed changing.

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lexical Ready Ready Preview Aug 5, 2026 5:58pm
lexical-playground Ready Ready Preview Aug 5, 2026 5:58pm

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 4, 2026

@etrepum etrepum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think the better solution here is to simply deprecate CAN_UNDO_COMMAND and CAN_REDO_COMMAND because HistoryExtension has signals that are always correct. Even with this fix, there are still bootstrapping issues if you start observing the commands after the editor is initialized because there's no way to know the initial states.

@LeSingh1

LeSingh1 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Agreed, and I checked before replying: syncFromHistoryState derives canUndo/canRedo straight from the stack lengths on every mutation, so the signals are already correct through a clear — it's only the two commands that go stale. And you're right that the fix doesn't close the gap, because a listener registered after init has no way to read the current value; commands are events, not state.

Happy to repoint this PR at the deprecation instead: @deprecated on CAN_UNDO_COMMAND and CAN_REDO_COMMAND pointing at HistoryExtension's signals, plus a note in the history docs. Or close it if you'd rather do that yourself. Which do you prefer?

@etrepum

etrepum commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Feel free to submit a PR with the deprecations and documentation, it's not a priority for me to personally create those kinds of PRs

@LeSingh1 LeSingh1 changed the title [lexical-history] Bug Fix: reset canUndo/canRedo on CLEAR_EDITOR_COMMAND [lexical] Deprecate CAN_UNDO_COMMAND and CAN_REDO_COMMAND in favour of HistoryExtension's signals Aug 5, 2026
@LeSingh1

LeSingh1 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Done in c4dd9a9 — retitled and repointed at the deprecation.

@deprecated JSDoc on both commands pointing at the signals, and an "Undo/redo availability" section in the @lexical/history README using getExtensionDependencyFromEditor with peek() and effect(). The commands still dispatch, matching how KEY_MODIFIER_COMMAND was handled.

I left the original CLEAR_EDITOR_COMMAND hunk in so anyone still on the deprecated path isn't left with an enabled undo button during the deprecation window — say the word and I'll drop it and its test so the deprecation lands on its own.

26/26 in packages/lexical-history, tsc and lint clean.

@etrepum etrepum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don’t think it makes sense to add code or tests relevant to the deprecated path, everything from the initial commit can be dropped.

The react-like code example would be better off using the useExtensionSignalValue hook than a manual effect (which would have to be in a useEffect in that environment)

A command only reports a change, so a listener registered after the editor
is initialized never sees the current value and has no way to read it.
HistoryExtension's canUndo / canRedo signals are derived from the history
stacks and always hold the current value.

Point both commands at the signals and document the replacement in the
@lexical/history README.
@LeSingh1
LeSingh1 force-pushed the fix/clear-editor-can-undo-redo branch from c4dd9a9 to 2668e99 Compare August 5, 2026 17:56
@LeSingh1

LeSingh1 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Done. Rebuilt the branch on main with only the deprecation — the initial commit's code and test are gone, so the diff is now just the JSDoc and the README. Swapped the example to useExtensionSignalValue, with the getExtensionDependencyFromEditor form kept for non-React callers. tsc and lint clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants