Repository: umaranis/svelte-lexical
Pull request #115: Add new `Clear Editor Content` documentation
Author: login: jeromew
Created: 2025-03-20T09:37:37Z | Merged: 2025-03-30T05:37:34Z



Diff:
diff --git a/packages/website/astro.config.mjs b/packages/website/astro.config.mjs
index 97c86cef..a619548e 100644
--- a/packages/website/astro.config.mjs
+++ b/packages/website/astro.config.mjs
@@ -33,6 +33,10 @@ export default defineConfig({
               label: 'Read Mode / Edit Mode',
               slug: 'guides/read-mode-edit-mode',
             },
+            {
+              label: 'Clear Editor Content',
+              slug: 'guides/clear-editor-content',
+            },
             {
               label: 'Customizing the theme',
               slug: 'guides/custom-theme',
diff --git a/packages/website/src/content/docs/guides/clear-editor-content.mdx b/packages/website/src/content/docs/guides/clear-editor-content.mdx
new file mode 100644
index 00000000..889c5cb7
--- /dev/null
+++ b/packages/website/src/content/docs/guides/clear-editor-content.mdx
@@ -0,0 +1,156 @@
+---
+title: Clear the content of the editor
+description: Explanation on how to remove all content of the editor
+---
+
+Sometimes you want to programmatically remove all content from the editor in order to start from a blank editor.
+
+The first thing to do is to get a reference to the `Editor`. This is explained on [Get Editor reference](get-reference-to-editor).
+
+This example will create a ClearButton that clears the content of the `Editor`. We will assume that you chose to get the reference to the `Editor` via the `getEditor` API.
+
+:::caution
+Let's repeat here that this `getEditor` API only works within the `Composer` context and `getEditor` call can only be made during component initialization.
+:::
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+	import { getEditor } from 'svelte-lexical';
+	const editor = getEditor();
+</script>
+
+<button>
+	Clear the content
+</button>
+```
+
+Now we want to call a function that will clear the content when the button is clicked. For this, we need to add an onclick listener on the button and then use the `editor.update(..)` API to give lexical a callback that it will call in a next update cycle to update the state of the editor.
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+        import { getEditor } from 'svelte-lexical';
+        const editor = getEditor();
++        function clearContent() {
++          // code to be added here
++        }
+</script>
+
+-<button>
++<button on:click={() => editor.update(clearContent)}>
+        Clear the content
+</button>
+```
+
+When `editor.update(..)` is called, the given callback has to build a new editor state and for this, we need to use the corresponding APIs.
+In order to clear the content, one way is to call `.clear()` on the `RootNode` of the content. So we need to first add a method that will give us access to the root node :
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+-        import { getEditor } from 'svelte-lexical';
++        import { getEditor, $getRoot as getRoot } from 'svelte-lexical';
+        const editor = getEditor();
+        function clearContent() {
+          // code to be added here
+        }
+</script>
+
+<button on:click={() => editor.update(clearContent)}>
+        Clear the content
+</button>
+```
+
+:::caution
+Note how `$getRoot` was renamed to `getRoot` during the import. This is necessary in order to not confuse `Svelte` as `$` is part of the `Svelte` semantics and `Svelte` will refuse to expose a function that starts with a `$`
+:::
+
+Next, in order to finalize the `ClearButton` component, we have to fill the `clearContent` method with the necessary call to `root.clear()`.
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+        import { getEditor, $getRoot as getRoot } from 'svelte-lexical';
+        const editor = getEditor();
+        function clearContent() {
+-          // code to be added here
++          const root = getRoot();
++          root.clear();
+        }
+</script>
+
+<button on:click={() => editor.update(clearContent)}>
+        Clear the content
+</button>
+```
+
+The `ClearButton` is now in its final state. Let’s add the button to MyEditor.svelte
+
+``` diff lang="svelte"
+// MyEditor.svelte
+<script lang="ts">
+	import {
+		Composer, ContentEditable, getEditor,
+		HorizontalRuleNode, HorizontalRulePlugin, RichTextPlugin
+	} from 'svelte-lexical';
+	import { theme } from 'svelte-lexical/dist/themes/default';
+	import MyToolbar from './MyToolbar.svelte';
++	import ClearButton from './ClearButton.svelte';
+
+	const initialConfig = {
+		theme: theme,
+		namespace: 'pg_demo',
+		nodes: [HorizontalRuleNode],
+		onError: (error: Error) => {
+			throw error;
+		}
+	};
+</script>
+
+<Composer {initialConfig}>
+	<div class="editor-shell svelte-lexical">
+		<MyToolbar />
++		<ClearButton/>
+		<div class="editor-container">
+			<div class="editor-scroller">
+				<div class="editor">
+					<ContentEditable />
+				</div>
+			</div>
+			<RichTextPlugin />
+			<HorizontalRulePlugin />
+		</div>
+	</div>
+</Composer>
+```
+
+
+As a pure educational scenario, and in order to show you that there is a lot more than `.clear()` in the lexical/svelte-lexical API, here is another version of the `ClearButton`: instead of calling `.clear()`, we select all the nodes under the root node of the `Editor` - just like a user would select all the text inside the editor - and then remove the selection.
+
+Here is the modified version of the `ClearButton` button :
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+        import { getEditor, $getRoot as getRoot } from 'svelte-lexical';
+        const editor = getEditor();
+        function clearContent() {
+          const root = getRoot();
+-          root.clear();
++          const selection = root.select(0, root.getChildrenSize());
++          selection.removeText();
+        }
+</script>
+
+<button on:click={() => editor.update(clearContent)}>
+        Clear the content
+</button>
+```
+
+
+If you are interested in the available APIs on the root node, you can check
+- the available methods on the `RootNote` class in the lexical API ([Lexical RootNode API](https://lexical.dev/docs/api/classes/lexical.RootNode))
+- and since `RootNode` inherits from `ElementNode`, the available methods on the `ElementNote` class in the lexical API ([Lexical ElementNode API](https://lexical.dev/docs/api/classes/lexical.ElementNode))
+
+For information, the `.clear()` method that we used earlier is defined by the `ElementNode` class.


Reviews:
user: login: umaranis
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-21T01:15:14Z
user: login: jeromew
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T09:03:03Z
user: login: jeromew
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T09:08:18Z
user: login: jeromew
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T09:20:04Z
user: login: jeromew
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T09:59:05Z

Review comments:
diff_hunk: @@ -0,0 +1,96 @@
+---
+title: Clear the content of the editor
+description: Explanation on how to remove all content of the editor
+---
+
+Sometimes you want to programmatically remove all content from the editor in order to start from a blank editor.
+
+The first thing to do is to get a reference to the `Editor`. This is explained on [Get Editor reference](get-reference-to-editor).
+
+This example will create a ClearButton that clears the content of the `Editor`. We will assume that you chose to get the reference to the `Editor` via the `getEditor` API.
+
+:::caution
+Let's repeat here that this `getEditor` API only works within the `Composer` context and `getEditor` call can only be made during component initialization.
+:::
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+	import { getEditor } from 'svelte-lexical';
+	const editor = getEditor();
+</script>
+
+<button on:click={() => editor.clear()}>
path: packages/website/src/content/docs/guides/clear-editor-content.mdx
user: login: umaranis
body: There is no clear method in the `editor` object. Am i missing something here? @jeromew 
created_at: 2025-03-21T01:15:13Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,96 @@
+---
+title: Clear the content of the editor
+description: Explanation on how to remove all content of the editor
+---
+
+Sometimes you want to programmatically remove all content from the editor in order to start from a blank editor.
+
+The first thing to do is to get a reference to the `Editor`. This is explained on [Get Editor reference](get-reference-to-editor).
+
+This example will create a ClearButton that clears the content of the `Editor`. We will assume that you chose to get the reference to the `Editor` via the `getEditor` API.
+
+:::caution
+Let's repeat here that this `getEditor` API only works within the `Composer` context and `getEditor` call can only be made during component initialization.
+:::
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+	import { getEditor } from 'svelte-lexical';
+	const editor = getEditor();
+</script>
+
+<button on:click={() => editor.clear()}>
path: packages/website/src/content/docs/guides/clear-editor-content.mdx
user: login: jeromew
body: oops. thanks for catching this. I mixed things up after I started with `editor.setEditable(false)`.
this is more complex than I thought. it seems there could be a `editor.clearEditor()` method, but only if LexicalClearEditorPlugin plugin is activated + LexicalClearEditorPlugin is not yet ported
for now I will look at what this plugin does internally and see if we can use this
created_at: 2025-03-21T09:03:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,96 @@
+---
+title: Clear the content of the editor
+description: Explanation on how to remove all content of the editor
+---
+
+Sometimes you want to programmatically remove all content from the editor in order to start from a blank editor.
+
+The first thing to do is to get a reference to the `Editor`. This is explained on [Get Editor reference](get-reference-to-editor).
+
+This example will create a ClearButton that clears the content of the `Editor`. We will assume that you chose to get the reference to the `Editor` via the `getEditor` API.
+
+:::caution
+Let's repeat here that this `getEditor` API only works within the `Composer` context and `getEditor` call can only be made during component initialization.
+:::
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+	import { getEditor } from 'svelte-lexical';
+	const editor = getEditor();
+</script>
+
+<button on:click={() => editor.clear()}>
path: packages/website/src/content/docs/guides/clear-editor-content.mdx
user: login: jeromew
body: BTW would it make sense for you / do you think it would be possible to upgrade lexical dependency to 0.28 ? on their website they do not mention in which version some APIs are available or not
created_at: 2025-03-21T09:08:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,96 @@
+---
+title: Clear the content of the editor
+description: Explanation on how to remove all content of the editor
+---
+
+Sometimes you want to programmatically remove all content from the editor in order to start from a blank editor.
+
+The first thing to do is to get a reference to the `Editor`. This is explained on [Get Editor reference](get-reference-to-editor).
+
+This example will create a ClearButton that clears the content of the `Editor`. We will assume that you chose to get the reference to the `Editor` via the `getEditor` API.
+
+:::caution
+Let's repeat here that this `getEditor` API only works within the `Composer` context and `getEditor` call can only be made during component initialization.
+:::
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+	import { getEditor } from 'svelte-lexical';
+	const editor = getEditor();
+</script>
+
+<button on:click={() => editor.clear()}>
path: packages/website/src/content/docs/guides/clear-editor-content.mdx
user: login: jeromew
body: I am a bit lost in the lexical code base ; they mention clearEditor on https://facebook.github.io/lexical-ios/documentation/lexical/editor/cleareditor() 
but I didn't expect there was yet another lexical project `lexical-ios`  for ios !
created_at: 2025-03-21T09:20:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,96 @@
+---
+title: Clear the content of the editor
+description: Explanation on how to remove all content of the editor
+---
+
+Sometimes you want to programmatically remove all content from the editor in order to start from a blank editor.
+
+The first thing to do is to get a reference to the `Editor`. This is explained on [Get Editor reference](get-reference-to-editor).
+
+This example will create a ClearButton that clears the content of the `Editor`. We will assume that you chose to get the reference to the `Editor` via the `getEditor` API.
+
+:::caution
+Let's repeat here that this `getEditor` API only works within the `Composer` context and `getEditor` call can only be made during component initialization.
+:::
+
+``` diff lang="svelte"
+// ClearButton.svelte
+<script lang="ts">
+	import { getEditor } from 'svelte-lexical';
+	const editor = getEditor();
+</script>
+
+<button on:click={() => editor.clear()}>
path: packages/website/src/content/docs/guides/clear-editor-content.mdx
user: login: jeromew
body: ok so i begin to realize now (it seems fair as lexical has to build & reconcile its model of the content) that there is really only one way to update the content of the editor and that is through a call to update(), either an explicit call to editor.update(...) or an implicit call like dispatchCommand(..)

the dispatchCommand mechanism is sometimes more powerful since it is the way different features collaborate ; for instance when the `CLEAR_EDITOR_COMMAND` is dispatched, the lexical-history can catch it and clear the history.

It seems to me that for now svelte-lexical does not re-export the lexical commands that are declared in https://github.com/facebook/lexical/blob/main/packages/lexical/src/LexicalCommands.ts and exported by https://github.com/facebook/lexical/blob/main/packages/lexical/src/index.ts

so now it gets clearer :
 - we can clear the contents via an update ; this should clear the editor while keeping history if the history editor is activated
 - or we can clear the contents via a 'CLEAR_EDITOR_COMMAND' but for this to work a port of LexicalClearEditorPlugin needs to be activated in the Composer + there needs to be a way to send the 'CLEAR_EDITOR_COMMAND'. In this case, if the history plugin is activated, it will also clear the history
 
 so it really depends on what is meant by 'Clear Editor Content' ;-)
 
 for now, I will change the PR and keep only the update mechanism.

created_at: 2025-03-21T09:59:05Z
author_association: CONTRIBUTOR

PR comments:
user: login: vercel[bot]
created_at: 2025-03-20T09:37:43Z
body: [vc]: #4OA1q+qBKFgwZGTWiHrO0gjMwJx4+0bAKf7ZWpK8XOY=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJzdmVsdGUtbGV4aWNhbC1wa2ciLCJyb290RGlyZWN0b3J5IjoicGFja2FnZXMvc3ZlbHRlLWxleGljYWwiLCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20vdW1hcmFuaXMtcHJvamVjdHMtMjQxNjZjY2Mvc3ZlbHRlLWxleGljYWwtcGtnL0djaWNxSHFRZXVHdVY0NXp3d1pwcWE5VXVhemsiLCJwcmV2aWV3VXJsIjoic3ZlbHRlLWxleGljYWwtcGtnLWdpdC1mb3JrLWotYjE4NjBjLXVtYXJhbmlzLXByb2plY3RzLTI0MTY2Y2NjLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiREVQTE9ZRUQiLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoic3ZlbHRlLWxleGljYWwtcGtnLWdpdC1mb3JrLWotYjE4NjBjLXVtYXJhbmlzLXByb2plY3RzLTI0MTY2Y2NjLnZlcmNlbC5hcHAifX0seyJuYW1lIjoic3ZlbHRlLWxleGljYWwtd2Vic2l0ZSIsInJvb3REaXJlY3RvcnkiOiJwYWNrYWdlcy93ZWJzaXRlIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3VtYXJhbmlzLXByb2plY3RzLTI0MTY2Y2NjL3N2ZWx0ZS1sZXhpY2FsLXdlYnNpdGUvNkdIMk1FZTV6Y2NwWWUzUHFqU0dmNTJFOEZvayIsInByZXZpZXdVcmwiOiJzdmVsdGUtbGV4aWNhbC13ZWJzaXRlLWdpdC1mby03OTFkNmEtdW1hcmFuaXMtcHJvamVjdHMtMjQxNjZjY2MudmVyY2VsLmFwcCIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiJzdmVsdGUtbGV4aWNhbC13ZWJzaXRlLWdpdC1mby03OTFkNmEtdW1hcmFuaXMtcHJvamVjdHMtMjQxNjZjY2MudmVyY2VsLmFwcCJ9fSx7Im5hbWUiOiJzdmVsdGUtbGV4aWNhbC1wbGF5Z3JvdW5kIiwicm9vdERpcmVjdG9yeSI6ImRlbW9zL3BsYXlncm91bmQiLCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20vdW1hcmFuaXMtcHJvamVjdHMtMjQxNjZjY2Mvc3ZlbHRlLWxleGljYWwtcGxheWdyb3VuZC9GYUJieE5pNk1UQjhUcDNRUkVpdnF4SnBWeUFVIiwicHJldmlld1VybCI6InN2ZWx0ZS1sZXhpY2FsLXBsYXlncm91bmQtZ2l0LTU4YTQ3YS11bWFyYW5pcy1wcm9qZWN0cy0yNDE2NmNjYy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6InN2ZWx0ZS1sZXhpY2FsLXBsYXlncm91bmQtZ2l0LTU4YTQ3YS11bWFyYW5pcy1wcm9qZWN0cy0yNDE2NmNjYy52ZXJjZWwuYXBwIn19XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **svelte-lexical-pkg** | ✅ Ready ([Inspect](https://vercel.com/umaranis-projects-24166ccc/svelte-lexical-pkg/GcicqHqQeuGuV45zwwZpqa9Uuazk)) | [Visit Preview](https://svelte-lexical-pkg-git-fork-j-b1860c-umaranis-projects-24166ccc.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/svelte-lexical-pkg-git-fork-j-b1860c-umaranis-projects-24166ccc.vercel.app?via=pr-comment-feedback-link) | Mar 21, 2025 0:20am |
| **svelte-lexical-playground** | ✅ Ready ([Inspect](https://vercel.com/umaranis-projects-24166ccc/svelte-lexical-playground/FaBbxNi6MTB8Tp3QREivqxJpVyAU)) | [Visit Preview](https://svelte-lexical-playground-git-58a47a-umaranis-projects-24166ccc.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/svelte-lexical-playground-git-58a47a-umaranis-projects-24166ccc.vercel.app?via=pr-comment-feedback-link) | Mar 21, 2025 0:20am |
| **svelte-lexical-website** | ✅ Ready ([Inspect](https://vercel.com/umaranis-projects-24166ccc/svelte-lexical-website/6GH2MEe5zccpYe3PqjSGf52E8Fok)) | [Visit Preview](https://svelte-lexical-website-git-fo-791d6a-umaranis-projects-24166ccc.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/svelte-lexical-website-git-fo-791d6a-umaranis-projects-24166ccc.vercel.app?via=pr-comment-feedback-link) | Mar 21, 2025 0:20am |




author_association: NONE
user: login: jeromew
created_at: 2025-03-20T12:31:59Z
body: Again, some checks are failing. I am not sure it is because of my commit / if I can do something about it (?)
author_association: CONTRIBUTOR
user: login: jeromew
created_at: 2025-03-21T12:24:12Z
body: I pushed a full review of the page + tested the snippets are working as expected
I suggest you review it by looking at https://github.com/umaranis/svelte-lexical/pull/115/files which combines the 2 commits

what do you think about exposing the LexicalCommands in the future ?
author_association: CONTRIBUTOR
user: login: jeromew
created_at: 2025-03-28T20:54:00Z
body: @umaranis Do you think the doc is ok or is it not what you expected ?
author_association: CONTRIBUTOR
user: login: umaranis
created_at: 2025-03-30T05:36:28Z
body: Thanks @jeromew. The docs are good.
Sorry for the delay in reviewing the PR.

Regarding the lexical commands, I think it would be good to expose wrappers that hide some of the complexity.
author_association: OWNER
user: login: jeromew
created_at: 2025-03-30T10:08:14Z
body: thanks @umaranis. I agree it is too early for the lexical commands and wrappers. I don't fully understand them for now.
author_association: CONTRIBUTOR