Skip to content

feat(text-editor): add clear method to clear content imperatively#4144

Open
jecrapo wants to merge 1 commit into
mainfrom
feat/text-editor-set-value
Open

feat(text-editor): add clear method to clear content imperatively#4144
jecrapo wants to merge 1 commit into
mainfrom
feat/text-editor-set-value

Conversation

@jecrapo

@jecrapo jecrapo commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Problem

limel-text-editor is a controlled component (it has a value prop), but assigning value only updates the editor when Stencil detects the prop changed. Because the editor debounces its change event, a consumer's bound value can legitimately lag the live document. That produces a case the prop can't express: clearing the editor by assigning '' when the previously rendered prop was already ''.

The clearest example is a chat-style "send box":

  1. The user types fast and presses send.
  2. The composer flushes, captures the text, emits the message, then sets its bound value back to '' to clear.
  3. Stencil batches the "catch-up" value and the clear into one render and commits only the final ''. Since the previously rendered value was already '', the prop goes '' → ''no change — so the editor never re-renders, @Watch('value') never fires, and the document keeps the sent text on screen.

The editor receives no signal at all in this case, so it cannot be fixed reactively from inside the component. flushPendingChanges() (added in #4128) solved the symmetric read problem for this same use case; this adds the write counterpart.

Change

Add an imperative clear() method to limel-text-editor (and its ProseMirror adapter) that empties the editor's document regardless of the prop's change detection:

  • discards any pending debounced change so it can't fire afterward and resurrect old content;
  • does nothing if the document is already empty (preserves the caret);
  • does not emit a change event (the caller cleared it, so no echo / re-entrancy).

Consumers that previously needed timing workarounds to clear (e.g. deferring by a frame) can call await editor.clear() instead.

// on send:
await editor.flushPendingChanges();        // read: make sure we have the full text
this.converseRequest.emit(this.value);
await editor.clear();                       // write: reliably empty, no timing hack

Backwards compatible (additive method only).

Tests

  • Spec: clear resolves, including readonly mode where no adapter is rendered.
  • E2E: clear empties content the value prop never caught up to; discards the pending change so no stale change is emitted; does not emit a change event.

Summary by CodeRabbit

  • New Features

    • Text editor component now exposes a clear() method for direct programmatic clearing of editor content, including in scenarios with debounced updates.
    • Clearing is designed to avoid emitting the editor’s change event.
  • Tests

    • Added end-to-end and unit tests validating clear() behavior across default and readonly modes.
    • Added coverage to ensure pending/debounced change emissions are discarded and no stale text is reported after clearing.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 89e698b4-8ff1-48a5-9bfc-9512fb0c4144

📥 Commits

Reviewing files that changed from the base of the PR and between d23be29 and df4fe99.

⛔ Files ignored due to path filters (1)
  • etc/lime-elements.api.md is excluded by !etc/lime-elements.api.md
📒 Files selected for processing (4)
  • src/components/text-editor/prosemirror-adapter/prosemirror-adapter.tsx
  • src/components/text-editor/text-editor.e2e.tsx
  • src/components/text-editor/text-editor.spec.tsx
  • src/components/text-editor/text-editor.tsx

📝 Walkthrough

Walkthrough

A new clear() imperative method is added to TextEditor and ProsemirrorAdapter. The adapter implementation cancels any pending debounced change, serializes current content to avoid redundant work if already empty, and applies the clear via updateView('') without emitting a change event. Unit and e2e tests cover content clearing, pending-change cancellation, and no-emission behavior.

Changes

clear imperative API

Layer / File(s) Summary
clear implementation in adapter and component
src/components/text-editor/text-editor.tsx, src/components/text-editor/prosemirror-adapter/prosemirror-adapter.tsx
TextEditor.clear delegates to adapterElement?.clear(). ProsemirrorAdapter.clear early-returns if the editor view is unavailable, cancels any pending debounced change, short-circuits if content is already empty, and otherwise calls updateView('') with change emission suppressed.
Unit and e2e tests
src/components/text-editor/text-editor.spec.tsx, src/components/text-editor/text-editor.e2e.tsx
Unit tests assert clear resolves in default and readonly modes. E2e tests verify that clear() empties the editor even when changes are pending, that pending typed changes are discarded and do not emit later via debounced change events, and that no change event is emitted.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • Lundalogik/lime-elements#4127: Modifies updateView in prosemirror-adapter to resync lastEmittedValue, which directly interacts with the programmatic update suppression path that the new clear method relies on.
  • Lundalogik/lime-elements#4128: Adds flushPendingChanges() and adjusts pending-value logic in the same adapter, closely related to the pending change cancellation introduced in clear.

Suggested labels

released

Suggested reviewers

  • CarlitoSweden
  • adrianschmidt
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding a clear method to the text-editor component for imperative content clearing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/text-editor-set-value

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Documentation has been published to https://lundalogik.github.io/lime-elements/versions/PR-4144/

@jecrapo jecrapo force-pushed the feat/text-editor-set-value branch from bdb0591 to d23be29 Compare June 23, 2026 09:31
@jecrapo jecrapo marked this pull request as ready for review June 23, 2026 09:35
@jecrapo jecrapo requested a review from a team as a code owner June 23, 2026 09:35
Assigning an empty `value` prop only clears the editor when the value
changes. Because the editor debounces its `change` event, a consumer's
bound value can lag the live document, so assigning `''` when the prop was
already `''` is skipped by change detection and leaves the content
untouched (for example, clearing the editor immediately after a send).

clear empties the editor regardless of the prop's change detection,
discarding any pending debounced change. It does not emit a `change`
event.
@jecrapo jecrapo force-pushed the feat/text-editor-set-value branch from d23be29 to df4fe99 Compare June 23, 2026 12:32
@jecrapo jecrapo changed the title feat(text-editor): add setValue method to set content imperatively feat(text-editor): add clear method to clear content imperatively Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant