fix(PersonMentionEditor): guard setEditable effect against re-entry loop

The disabled-state effect calls editor.setEditable, which triggers a
ProseMirror transaction → onUpdate → bind:value/mentionedPersons writes →
host re-render → child prop pass-through → effect re-fires. Without an
idempotence check, this exceeds Svelte's effect_update_depth and crashes
every consuming spec (TranscriptionBlock 22/22). Compare editor.isEditable
against the desired value first; only call setEditable when it actually
needs to change.

Follow-up to 6ef888a1.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-29 16:18:40 +02:00
parent fa7b97acdc
commit ba88febc77

View File

@@ -241,8 +241,15 @@ onDestroy(() => {
// Keep editor in sync with the reactive `disabled` prop. Tiptap's setEditable
// flips contenteditable on the inner DOM and stops accepting input — matches
// the textarea's old `disabled` semantics for keyboard users (WCAG 2.1.1).
//
// Guard: setEditable triggers a ProseMirror transaction which fires onUpdate;
// onUpdate writes through bind:value / bind:mentionedPersons. Without this
// idempotence check, the effect would loop on every prop pass-through.
$effect(() => {
editor?.setEditable(!disabled);
const shouldBeEditable = !disabled;
if (editor && editor.isEditable !== shouldBeEditable) {
editor.setEditable(shouldBeEditable);
}
});
</script>