From 9ff629d198aacac60ab0602b45269d24c9cc2cdf Mon Sep 17 00:00:00 2001 From: Tadeu Tupinamba Date: Tue, 3 Mar 2026 10:34:07 -0300 Subject: [PATCH 1/2] fix(comments): reduce sidebar jitter when clicking comments (SD-2034) Clicking a comment near the bottom of the sidebar caused the scrollbar to flash because totalHeight oscillated during collision avoidance recalculation and height remeasurements. Three fixes: - Add CSS transition on section-wrapper min-height so height changes are smooth instead of causing abrupt scrollbar appearance/disappearance - Increase ESTIMATED_HEIGHT from 80 to 110 to better match actual comment card sizes, reducing visual overlap before measurement - Fix scroll-to-comment: increase delay from 100ms to 400ms so the comment-placeholder CSS transition (300ms) completes before checking visibility, and use rect.bottom instead of rect.top for the lower bound check --- .../src/components/CommentsLayer/FloatingComments.vue | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue b/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue index 990ac5879a..c994a91835 100644 --- a/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue +++ b/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue @@ -10,7 +10,7 @@ import { useCommentsStore } from '@superdoc/stores/comments-store'; import { useSuperdocStore } from '@superdoc/stores/superdoc-store'; import CommentDialog from '@superdoc/components/CommentsLayer/CommentDialog.vue'; -const ESTIMATED_HEIGHT = 80; +const ESTIMATED_HEIGHT = 110; const OBSERVER_MARGIN = 600; // Layout algorithm: positions comments in a single column with collision avoidance. @@ -323,18 +323,19 @@ watch(activeComment, () => { if (!key) return; nextTick(() => { + // 400ms: wait for .comment-placeholder CSS transition (300ms) + buffer scrollTimer = setTimeout(() => { const el = placeholderRefs.value[key]; if (!el) return; const rect = el.getBoundingClientRect(); const margin = 80; - const isVisible = rect.top >= margin && rect.top <= window.innerHeight - margin; + const isVisible = rect.top >= margin && rect.bottom <= window.innerHeight - margin; if (!isVisible) { el.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } - }, 100); + }, 400); }); }); @@ -499,5 +500,7 @@ onBeforeUnmount(() => { display: flex; align-items: flex-start; justify-content: flex-start; + /* SD-2034: smooth min-height changes to prevent scrollbar flash */ + transition: min-height 0.5s ease-out; } From 18e4a131e41ba94c2a2acea1a51b947473843a48 Mon Sep 17 00:00:00 2001 From: Tadeu Tupinamba Date: Tue, 3 Mar 2026 18:54:42 -0300 Subject: [PATCH 2/2] fix(comments): handle tall cards in scroll-to-comment visibility check When a comment card is taller than the viewport, the rect.bottom check always fails, causing scrollIntoView to fire on every click. Fall back to checking only rect.top for cards that exceed the available height. --- .../src/components/CommentsLayer/FloatingComments.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue b/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue index c994a91835..81786e9b47 100644 --- a/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue +++ b/packages/superdoc/src/components/CommentsLayer/FloatingComments.vue @@ -330,7 +330,11 @@ watch(activeComment, () => { const rect = el.getBoundingClientRect(); const margin = 80; - const isVisible = rect.top >= margin && rect.bottom <= window.innerHeight - margin; + const availableHeight = window.innerHeight - 2 * margin; + const isVisible = + rect.height > availableHeight + ? rect.top >= margin + : rect.top >= margin && rect.bottom <= window.innerHeight - margin; if (!isVisible) { el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });